Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
willie68 committed Sep 8, 2021
2 parents b560986 + 786d980 commit 31fe393
Show file tree
Hide file tree
Showing 27 changed files with 1,564 additions and 32 deletions.
963 changes: 963 additions & 0 deletions README-de.md

Large diffs are not rendered by default.

22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,21 @@ If you see a field with the red warning "Action not defined", there is a misconf
Buttons or actions can have several statuses. Depending on the situation, different icons are then displayed there. When a command is running, the hourglass is usually displayed. The turning position of the hourglass shows how many commands are currently being carried out. (Yes, actions can contain a command list)
In the case of so-called **multi**-actions, this action runs through a list of actions. The 1st action is carried out with the 1st press, the 2nd with the 2nd press and so on. The respective status is represented by the icon of the corresponding action.

As already mentioned, an action can contain several commands. (The "Hello World" action contains e.g. 3 commands: start notepad, wait a few seconds, write "Hello ReCoS"
As already mentioned, an action can contain several commands. (The "Hello World" action contains e.g. 3 commands: start notepad, wait a few seconds, write "Hello ReCoS")

# ReCoS Admin - Web Admin Interface

Writing to the service will be protected with a password. You can set this password in the service configuration. The default password is `recosadmin`. The username is `admin`. (But will not need this, until you try to access the Service interfaces directly)
The WebAdmin is used to configure the ReCoS system.

To deactivate password check simply add an empty password to the configuration.
All modifying functions are password protected. You can set this password in the WebAdmin. The standard password is `recosadmin`. To change, go to the icon at the top right and select Settings

![taskbar_1](documentation/assets/pwd_2.png)

In the following dialog you will find the password setting under the ReCoS Password tab

![taskbar_1](documentation/assets/pwd_1.png)

As usual, you have to enter your old password as well as your new password twice. To deactivate the password check, simply use a blank password.

## Action Wizard

Expand Down Expand Up @@ -116,11 +124,15 @@ In the Admin Client you can then see what the wizard has generated for you.

![image-20210331160145334](documentation/assets/aw_05.png)

## Exchange of profiles, actions and configured pages

You can export and re-import entire profiles, pages and individual actions. (e.g. to share them with friends) For various actions, you have to assure that the actions will still work after an import. In the case of the "Execute program" command, the path to the executable file is usually in the configuration. This can of course be different on your system than the one on your friend's system.

# ReCoS Service

The service is the main component of the ReCoS. This is the unit of work, doing all the nice things. But you will only see a little Icon in the taskbar. And there is a small context menu.
The service is the main component of the ReCoS. This is the unit of work, doing all the nice thing s. But you will only see a little Icon in the taskbar. And there is a small context menu.

![image-20210412112204299](./documentation/assets/taskbar_1.png)
as

Here you can directly start the web interface or the admin client. And you can register the service to automatically start on windows start. Next option is to edit the service.yaml file, which contains all configuration for the service itself. Normally you don't need to do here anything, but just in case...
The last Menu entry is for shutting down the Service.
Expand Down
3 changes: 1 addition & 2 deletions build_all.cmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
@echo off
".\3rd party\GoVersionSetter.exe" -i
rem ".\3rd party\GoVersionSetter.exe" -i
".\3rd party\GoVersionSetter.exe" -e npm -f ./webclient/recosadmin/package.json
".\3rd party\GoVersionSetter.exe" -e npm -f ./webclient/RecosUI/package.json
".\3rd party\GoVersionSetter.exe" -e npm -f ./webclient/recoscli2/package.json
".\3rd party\GoVersionSetter.exe" -e iss -f ./install/setup.iss -o MyAppVersion
".\3rd party\GoVersionSetter.exe" -e vs -f ./integrations/streamdeck/StreamDeckService/StreamDeckService.csproj
".\3rd party\GoVersionSetter.exe" -e gores -f ./service/winres/winres.json -o RT_MANIFEST/#1/0409/identity/version,RT_VERSION/#1/0000/fixed/file_version,RT_VERSION/#1/0000/fixed/product_version,RT_VERSION/#1/0000/info/0409/ProductVersion,RT_VERSION/#1/0000/info/0409/FileVersion
Expand Down
Binary file added documentation/README-de.pdf
Binary file not shown.
Binary file modified documentation/README.pdf
Binary file not shown.
Binary file added documentation/assets/pwd_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/assets/pwd_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions install/setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define MyAppName "ReCoS"
;version number set by GoVersionSetter.
#define MyAppVersion "0.3.97"
#define MyAppVersion "0.3.98"
#define MyAppPublisher "MCS Media Computer Software"
#define MyAppURL "https://www.wk-music.de"
#define MyAppExeName "recos-service.exe"
Expand Down Expand Up @@ -42,12 +42,17 @@ Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescrip
[Files]
Source: "..\service\recos-service.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\documentation\README.pdf"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\documentation\README-de.pdf"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\integrations\streamdeck\StreamDeckService\bin\Release\net5.0-windows\publish\*"; DestDir: "{app}\streamdeck"; Flags: ignoreversion recursesubdirs

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\Readme english"; Filename: "{app}\README.pdf"
Name: "{group}\Readme deutsch"; Filename: "{app}\README-de.pdf"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"
Filename: "{app}\README.pdf"; Flags: nowait postinstall skipifsilent shellexec; Languages: english
Filename: "{app}\README-de.pdf"; Flags: nowait postinstall skipifsilent shellexec; Languages: german
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>sd_logo.ico</ApplicationIcon>
<Version>0.3.97</Version>
<Version>0.3.98</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion release_build.cmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@echo off
".\3rd party\GoVersionSetter.exe" -i -m
".\3rd party\GoVersionSetter.exe" -i
".\3rd party\GoVersionSetter.exe" -e npm -f ./webclient/recosadmin/package.json
".\3rd party\GoVersionSetter.exe" -e npm -f ./webclient/RecosUI/package.json
".\3rd party\GoVersionSetter.exe" -e iss -f ./install/setup.iss -o MyAppVersion
Expand Down
Binary file removed service/README.pdf
Binary file not shown.
43 changes: 43 additions & 0 deletions service/api/routes/configapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"image"
"image/png"
Expand All @@ -27,6 +28,7 @@ import (
"wkla.no-ip.biz/remote-desk-service/api"
"wkla.no-ip.biz/remote-desk-service/api/handler"
"wkla.no-ip.biz/remote-desk-service/config"
"wkla.no-ip.biz/remote-desk-service/error/serror"
clog "wkla.no-ip.biz/remote-desk-service/logging"
"wkla.no-ip.biz/remote-desk-service/pac"
"wkla.no-ip.biz/remote-desk-service/pkg"
Expand Down Expand Up @@ -55,6 +57,7 @@ func ConfigRoutes() *chi.Mux {
router.With(handler.AuthCheck()).Post("/integrations/{integname}", PostInteg)
router.Get("/credits", GetCredits)
router.Get("/networks", GetNetworks)
router.With(handler.AuthCheck()).Post("/password", PostChangePassword)
initIconMapper()
return router
}
Expand Down Expand Up @@ -448,3 +451,43 @@ func getNetworkList() []IpName {

return ips
}

// PostChangePassword post a new config
func PostChangePassword(response http.ResponseWriter, request *http.Request) {
// config.Save()
decoder := json.NewDecoder(request.Body)
var params map[string]interface{}
err := decoder.Decode(&params)
if err != nil {
clog.Logger.Errorf("Error reading json body: %v", err)
api.Err(response, request, err)
return
}

password, ok := params["password"]
if ok {
clog.Logger.Infof("password: %s", password)
}

newpassword, ok := params["newpassword"]
if ok {
clog.Logger.Infof("newpassword: %s", newpassword)
}

repeatpassword, ok := params["repeatpassword"]
if ok {
clog.Logger.Infof("repeat: %s", repeatpassword)
}
if password != config.Get().Password {
api.Err(response, request, serror.Unauthorized(nil))
return
}
if newpassword != repeatpassword {
api.Err(response, request, serror.BadRequest(errors.New("new password not identically")))
return
}
localConfig := config.Get()
localConfig.Password = newpassword.(string)
config.Save()
render.JSON(response, request, serror.New(http.StatusOK, "password changed"))
}
81 changes: 81 additions & 0 deletions service/api/routes/profilesapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"sort"
"strings"

"wkla.no-ip.biz/remote-desk-service/pkg/transformer"

"github.com/go-chi/chi"
"github.com/go-chi/render"
"wkla.no-ip.biz/remote-desk-service/api"
Expand All @@ -28,6 +30,8 @@ func ProfilesRoutes() *chi.Mux {
router.With(handler.AuthCheck()).Delete("/{profileName}", DeleteProfile)
router.Get("/{profileName}/export", GetExportProfile)
router.Get("/{profileName}/actions/{actionName}/export", GetExportAction)
router.Get("/{profileName}/pages/{pageName}/export", GetExportPage)
router.With(handler.AuthCheck()).Post("/{profileName}/combine/", PostCombine)
return router
}

Expand Down Expand Up @@ -250,3 +254,80 @@ func GetExportAction(response http.ResponseWriter, request *http.Request) {
response.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.action\"", actionName))
render.Data(response, request, body)
}

// GetExportPage exporting a page from a profile as a file
func GetExportPage(response http.ResponseWriter, request *http.Request) {
profileName, err := api.Param(request, "profileName")
if err != nil {
clog.Logger.Debug("Error reading profile name: \n" + err.Error())
api.Err(response, request, err)
return
}

profile, ok := getProfile(profileName)
if !ok {
clog.Logger.Debugf("Profile %s not found", profileName)
api.NotFound(response, request, "profile", profileName)
return
}

pageName, err := api.Param(request, "pageName")
if err != nil {
clog.Logger.Debug("Error reading page name: \n" + err.Error())
api.Err(response, request, err)
return
}

exchange, err := transformer.ExportPage(profile, pageName)
if err != nil {
clog.Logger.Debug("Error getting page: \n" + err.Error())
api.Err(response, request, err)
return
}

body, err := json.Marshal(exchange)
if err != nil {
clog.Logger.Debug("Error serialising action: \n" + err.Error())
api.Err(response, request, err)
return
}

response.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.page\"", pageName))
render.Data(response, request, body)
}

// PostCombine combines an export file with a profile
func PostCombine(response http.ResponseWriter, request *http.Request) {
profileName, err := api.Param(request, "profileName")
if err != nil {
clog.Logger.Debug("Error reading profile name: \n" + err.Error())
api.Err(response, request, err)
return
}

profile, ok := getProfile(profileName)
if !ok {
clog.Logger.Debugf("Profile %s not found", profileName)
api.NotFound(response, request, "profile", profileName)
return
}

decoder := json.NewDecoder(request.Body)
var profileExchange models.ProfileExchange
err = decoder.Decode(&profileExchange)
if err != nil {
clog.Logger.Debug("Error reading json body:" + err.Error())
api.Err(response, request, err)
return
}

newProfile, err := transformer.CombineProfile(profile, profileExchange)
if err != nil {
clog.Logger.Debug("Error reading json body:" + err.Error())
api.Err(response, request, err)
return
}

render.Status(request, http.StatusCreated)
render.JSON(response, request, newProfile)
}
2 changes: 1 addition & 1 deletion service/cmd/Service.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ func onReady() {
os.Exit(1)
}

serviceConfig = config.Get()
serviceConfig = *config.Get()
initConfig()

clog.Logger.Info("service is starting")
Expand Down
4 changes: 2 additions & 2 deletions service/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ var config = Config{
var File = "config/service.yaml"

// Get returns loaded config
func Get() Config {
return config
func Get() *Config {
return &config
}

// Load loads the config
Expand Down
42 changes: 42 additions & 0 deletions service/pkg/models/inout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package models

type ExchangeType string

const (
ExchangePage ExchangeType = "pages"
ExchangeAction = "actions"
)

// Profile is the container for different pages. In UI you can switch between Profiles. Every Profile consist of a name and different pages to navigate between
type ProfileExchange struct {
// Name of this profile
Name string `json:"name"`
// Description of this action for information
Description string `json:"description"`
// Type of the exchange format
Type ExchangeType `json:"type"`
// Pages are the UI structure for the different pages
Pages []*Page `json:"pages"`
// Actions contains the action definitions
Actions []*Action `json:"actions"`
}

// HasPage checking if the profile has a page with that name
func (p *ProfileExchange) HasPage(pageName string) bool {
for _, page := range p.Pages {
if page.Name == pageName {
return true
}
}
return false
}

// HasAction checking if the profile has an action with that name
func (p *ProfileExchange) HasAction(actionName string) bool {
for _, action := range p.Actions {
if action.Name == actionName {
return true
}
}
return false
}
30 changes: 30 additions & 0 deletions service/pkg/models/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ func (p *Profile) Copy() Profile {
return profile
}

// HasAction checking if the profile has an action with that name
func (p *Profile) HasAction(actionName string) bool {
for _, action := range p.Actions {
if action.Name == actionName {
return true
}
}
return false
}

// GetAction getting the named action from this profile or an error
func (p *Profile) GetAction(actionName string) (*Action, error) {
for _, action := range p.Actions {
Expand All @@ -177,6 +187,26 @@ func (p *Profile) GetAction(actionName string) (*Action, error) {
return nil, fmt.Errorf("no action with name %s found.", actionName)
}

// HasPage checking if the profile has a page with that name
func (p *Profile) HasPage(pageName string) bool {
for _, page := range p.Pages {
if page.Name == pageName {
return true
}
}
return false
}

// GetAction getting the named action from this profile or an error
func (p *Profile) GetPage(pageName string) (*Page, error) {
for _, page := range p.Pages {
if page.Name == pageName {
return &page, nil
}
}
return nil, fmt.Errorf("no page with name %s found.", pageName)
}

// Copy make a deep copy of this action
func (a *Action) Copy() *Action {
action := Action{
Expand Down
Loading

0 comments on commit 31fe393

Please sign in to comment.