Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
S
SHMCamStudio
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SexHackMe
SHMCamStudio
Commits
f189822b
Commit
f189822b
authored
Dec 02, 2024
by
nextime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Configurable buttons/actions
parent
f5af9770
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
237 additions
and
111 deletions
+237
-111
shmcamstudio.conf
shmcamstudio.conf
+123
-1
guiutils.py
shmcs/guiutils.py
+32
-0
panel.py
shmcs/panel.py
+40
-57
webpanel.py
shmcs/webpanel.py
+31
-3
index.html
templates/index.html
+11
-50
No files found.
shmcamstudio.conf
View file @
f189822b
...
@@ -26,9 +26,131 @@ button_width = 20
...
@@ -26,9 +26,131 @@ button_width = 20
button_height
=
2
button_height
=
2
font_size
=
12
font_size
=
12
[
OBS
:
mdma
]
[
OBS
:
mdma
]
host
=
192
.
168
.
42
.
115
host
=
192
.
168
.
42
.
115
port
=
4455
port
=
4455
password
=
motorol4
password
=
motorol4
# OUTPUT are shenes on OBS sending to a specific stream, can be a rtmp stream with
# OBS multistream plugin or a virtual cam, both the included in OBS or the ones
# from a plugin.
[
OUTPUT
:
smleeloo
]
obs
=
leeloo
scene
=
LIVE
SFW
source_title
=
5
source_closed
=
4
source_tease
=
3
[
OUTPUT
:
smstefy
]
obs
=
slut
scene
=
live
SFW
source_title
=
5
source_closed
=
4
source_tease
=
3
[
OUTPUT
:
shine
]
obs
=
slut
scene
=
SHINE
source_title
=
4
source_closed
=
2
source_tease
=
3
#[OUTPUT:livejasmin]
#obs = slut
#scene = LIVE JM
#source_title = 4,5
#source_closed = 3
#source_tease = 2
# BUTTON:<rownum>:<button_name>
[
BUTTON
:
1
:
private_shine
]
title
=
Private
Shine
action
=
private_shine
color
=
green
[
BUTTON
:
1
:
private_stefy
]
title
=
Private
Stefy
action
=
private_stefy
color
=
green
[
BUTTON
:
1
:
private_leelo
]
title
=
Private
Leeloo
action
=
private_leeloo
color
=
green
#[BUTTON:1:private_jasmine]
#title = Private Jasmine
#action = private_jasmine
#color = green
[
BUTTON
:
2
:
shine_openclose
]
title
=
Open
/
Close
Shine
action
=
shine_openclose
color
=
orange
[
BUTTON
:
2
:
stefy_openclose
]
title
=
Open
/
Close
Stefy
action
=
stefy_openclose
color
=
orange
[
BUTTON
:
2
:
leelo_openclose
]
title
=
Open
/
Close
Leeloo
action
=
leelo_openclose
color
=
orange
#[BUTTON:2:leelo_livejasmine]
#title = Open/Close JASM
#action = jasmine_openclose
[
BUTTON
:
3
:
tease_all
]
title
=
Tease
ALL
action
=
tease_all
color
=
blue
[
BUTTON
:
3
:
tease
]
title
=
Tease
action
=
tease
color
=
blue
[
BUTTON
:
3
:
open_all
]
title
=
Open
ALL
action
=
open_all
color
=
blue
[
ACTION
:
private_shine
]
execute
= /
usr
/
local
/
bin
/
smblur_private
[
ACTION
:
private_stefy
]
execute
= /
usr
/
local
/
bin
/
smblur_private_stefy
[
ACTION
:
private_leeloo
]
execute
= /
usr
/
local
/
bin
/
smblur_private_leeloo
#[ACTION:private_jasmine]
#execute = /usr/local/bin/smblur_private_jasmin
[
ACTION
:
leelo_openclose
]
execute
= /
usr
/
local
/
bin
/
smblur_leelo
[
ACTION
:
shine_openclose
]
execute
= /
usr
/
local
/
bin
/
smblur_shine
[
ACTION
:
stefy_openclose
]
execute
= /
usr
/
local
/
bin
/
smblur_stefy
#[ACTION:jasmine_openclose]
#execute = /usr/local/bin/smblur_jasmin
[
ACTION
:
tease_all
]
execute
= /
usr
/
local
/
bin
/
smblur_tease
[
ACTION
:
tease
]
execute
= /
usr
/
local
/
bin
/
smblur_teaseall
[
ACTION
:
open_all
]
execute
= /
usr
/
local
/
bin
/
smblur_clean
shmcs/guiutils.py
0 → 100644
View file @
f189822b
# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
def
get_buttons
():
r
=
1
buttons
=
{}
while
r
>=
1
and
r
<
10
:
buttons
[
r
]
=
{}
for
s
in
[
x
for
x
in
config
.
sections
()
if
'BUTTON:'
+
str
(
r
)
+
':'
in
x
]:
values
=
config
.
items
(
s
)
if
len
(
values
)
>
0
:
buttons
[
r
][
s
.
split
(
':'
,
2
)[
2
]]
=
{}
for
t
in
values
:
buttons
[
r
][
s
.
split
(
':'
,
2
)[
2
]][
t
[
0
]]
=
t
[
1
]
r
=
r
+
1
if
len
(
buttons
[
r
-
1
]
.
keys
())
<
1
:
del
(
buttons
[
r
-
1
])
r
=
0
numrows
=
len
(
buttons
.
keys
())
return
buttons
,
numrows
shmcs/panel.py
View file @
f189822b
...
@@ -20,7 +20,7 @@ import webbrowser
...
@@ -20,7 +20,7 @@ import webbrowser
import
sys
import
sys
import
os
import
os
from
utils
import
run_command
from
utils
import
run_command
from
guiutils
import
get_buttons
class
VideoPlayer
:
class
VideoPlayer
:
def
__init__
(
self
,
master
,
video_url
):
def
__init__
(
self
,
master
,
video_url
):
...
@@ -58,6 +58,7 @@ class VideoPlayer:
...
@@ -58,6 +58,7 @@ class VideoPlayer:
# Play the video
# Play the video
self
.
player
.
play
()
self
.
player
.
play
()
def
create_panel_gui
():
def
create_panel_gui
():
# Create the main window
# Create the main window
window
=
tk
.
Tk
()
window
=
tk
.
Tk
()
...
@@ -77,65 +78,47 @@ def create_panel_gui():
...
@@ -77,65 +78,47 @@ def create_panel_gui():
fright
=
tk
.
Frame
(
window
)
fright
=
tk
.
Frame
(
window
)
fright
.
pack
(
side
=
tk
.
RIGHT
,
fill
=
tk
.
BOTH
,
expand
=
True
)
fright
.
pack
(
side
=
tk
.
RIGHT
,
fill
=
tk
.
BOTH
,
expand
=
True
)
# Frame for the first two rows in the right frame
frame1
=
tk
.
Frame
(
fright
)
frame1
.
pack
(
fill
=
tk
.
BOTH
,
expand
=
True
)
# Buttons configuration
# Buttons configuration
buttons_row0
=
[
buttons
,
numrows
=
get_buttons
()
(
'PRIVATE STEFY'
,
'smblur_private_stefy'
),
print
(
numrows
,
buttons
)
(
'PRIVATE LEELOO'
,
'smblur_private_leeloo'
),
(
'PRIVATE JASMIN'
,
'smblur_private_jasmin'
),
(
'PRIVATE OTHER'
,
'smblur_private'
)
bh
=
int
(
55
/
numrows
)
]
if
numrows
>
0
:
row
=
1
buttons_row1
=
[
bframes
=
{}
(
'OPEN/CLOSE STEFY'
,
'smblur_stefy'
),
while
row
<=
numrows
:
(
'OPEN/CLOSE LEELOO'
,
'smblur_leeloo'
),
# create the frame for this row
(
'OPEN/CLOSE JASMIN'
,
'smblur_jasmin'
),
bframes
[
row
]
=
tk
.
Frame
(
fright
)
(
'OPEN/CLOSE OTHERS'
,
'smblur_shine'
)
bframes
[
row
]
.
pack
(
fill
=
tk
.
BOTH
,
expand
=
True
)
]
# Calculate button width
# Create buttons for the first two rows
bw
=
int
(
100
/
len
(
buttons
[
row
]
.
keys
()))
for
j
,
(
text
,
command
)
in
enumerate
(
buttons_row0
):
button
=
tk
.
Button
(
frame1
,
text
=
text
,
font
=
helv36
,
width
=
25
,
height
=
15
,
bg
=
"green"
,
fg
=
"white"
,
# add the buttons
command
=
lambda
cmd
=
command
:
run_command
(
cmd
))
col
=
0
button
.
grid
(
row
=
0
,
column
=
j
,
sticky
=
'nsew'
)
print
(
buttons
[
row
])
for
b
in
buttons
[
row
]
.
keys
():
for
j
,
(
text
,
command
)
in
enumerate
(
buttons_row1
):
command
=
None
button
=
tk
.
Button
(
frame1
,
text
=
text
,
font
=
helv36
,
width
=
25
,
height
=
15
,
bg
=
"green"
,
fg
=
"white"
,
if
config
.
has_section
(
'ACTION:'
+
buttons
[
row
][
b
][
'action'
]):
command
=
lambda
cmd
=
command
:
run_command
(
cmd
))
command
=
config
.
get
(
'ACTION:'
+
buttons
[
row
][
b
][
'action'
],
'execute'
,
fallback
=
None
)
button
.
grid
(
row
=
1
,
column
=
j
,
sticky
=
'nsew'
)
color
=
buttons
[
row
][
b
][
'color'
]
# Configure the columns in the first frame
print
(
command
)
for
i
in
range
(
4
):
button
=
tk
.
Button
(
bframes
[
row
],
text
=
buttons
[
row
][
b
][
'title'
],
font
=
helv36
,
width
=
bw
,
height
=
bh
,
bg
=
color
,
fg
=
"white"
,
frame1
.
grid_columnconfigure
(
i
,
weight
=
1
)
# Frame for the third row in the right frame
frame2
=
tk
.
Frame
(
fright
)
frame2
.
pack
(
fill
=
tk
.
BOTH
,
expand
=
True
)
# Row 2 with 3 buttons
buttons_row2
=
[
(
'TEASE'
,
'smblur_tease'
),
(
'TEASE ALL'
,
'smblur_teaseall'
),
(
'OPEN'
,
'smblur_clean'
)
]
# Create buttons for the third row
for
j
,
(
text
,
command
)
in
enumerate
(
buttons_row2
):
button
=
tk
.
Button
(
frame2
,
text
=
text
,
font
=
helv36
,
width
=
30
,
height
=
25
,
bg
=
"blue"
,
fg
=
"white"
,
command
=
lambda
cmd
=
command
:
run_command
(
cmd
))
command
=
lambda
cmd
=
command
:
run_command
(
cmd
))
button
.
grid
(
row
=
0
,
column
=
j
,
sticky
=
'nsew'
)
button
.
grid
(
row
=
0
,
column
=
col
,
sticky
=
'nsew'
)
col
=
col
+
1
# Configure the columns in the second frame
# Configure the columns in the frame
for
i
in
range
(
3
):
for
i
in
range
(
len
(
buttons
[
row
]
.
keys
())):
frame2
.
grid_columnconfigure
(
i
,
weight
=
1
)
bframes
[
row
]
.
grid_columnconfigure
(
i
,
weight
=
1
)
row
=
row
+
1
# Add a button to open web interface
# Add a button to open web interface
web_button
=
tk
.
Button
(
frame2
,
text
=
"Open Web Interface"
,
web_button
=
tk
.
Button
(
bframes
[
row
-
1
]
,
text
=
"Open Web Interface"
,
command
=
lambda
:
webbrowser
.
open
(
'http://localhost:5000'
),
command
=
lambda
:
webbrowser
.
open
(
'http://localhost:5000'
),
bg
=
"purple"
,
fg
=
"white"
,
font
=
helv36
)
bg
=
"purple"
,
fg
=
"white"
,
font
=
helv36
,
height
=
2
)
web_button
.
grid
(
row
=
1
,
column
=
1
,
sticky
=
'nsew'
)
web_button
.
grid
(
row
=
1
,
column
=
1
,
sticky
=
'nsew'
)
return
window
return
window
...
...
shmcs/webpanel.py
View file @
f189822b
...
@@ -17,20 +17,48 @@ from flask import Flask, render_template, request
...
@@ -17,20 +17,48 @@ from flask import Flask, render_template, request
from
utils
import
check_port_available
,
run_command
,
create_daemon
from
utils
import
check_port_available
,
run_command
,
create_daemon
import
sys
import
sys
import
os
import
os
from
guiutils
import
get_buttons
# Flask App Setup
# Flask App Setup
flask_app
=
Flask
(
'SHMCamStudio'
,
template_folder
=
TEMPLATE_DIR
)
flask_app
=
Flask
(
'SHMCamStudio'
,
template_folder
=
TEMPLATE_DIR
)
@
flask_app
.
route
(
'/'
)
@
flask_app
.
route
(
'/'
)
def
index
():
def
index
():
return
render_template
(
'index.html'
,
commands
=
COMMANDS
)
buttons
,
numrows
=
get_buttons
()
row
=
1
style_rows
=
""
htmlbuttons
=
""
if
numrows
>
0
:
while
row
<=
numrows
:
bspan
=
int
(
12
/
len
(
buttons
[
row
]
.
keys
()))
style_rows
=
style_rows
+
"
\n
.button_row"
+
str
(
row
)
+
" {
\n
grid-column: span "
+
str
(
bspan
)
+
";
\n
}
\n
"
col
=
0
htmlbuttons
=
htmlbuttons
+
"<div class='button_row'>"
for
b
in
buttons
[
row
]
.
keys
():
command
=
buttons
[
row
][
b
][
'action'
]
color
=
buttons
[
row
][
b
][
'color'
]
htmlbuttons
=
htmlbuttons
+
"""<button style="color:white;background-color:"""
+
color
+
""";" class="button private button_row"""
+
str
(
row
)
+
"""" onclick="executeCommand('"""
+
command
+
"""')">
"""
+
buttons
[
row
][
b
][
'title'
]
+
"""
</button>"""
htmlbuttons
=
htmlbuttons
+
"</div>"
row
=
row
+
1
return
render_template
(
'index.html'
,
commands
=
COMMANDS
,
style_rows
=
style_rows
,
htmlbuttons
=
htmlbuttons
)
@
flask_app
.
route
(
'/execute'
,
methods
=
[
'POST'
])
@
flask_app
.
route
(
'/execute'
,
methods
=
[
'POST'
])
def
execute
():
def
execute
():
command_key
=
request
.
form
.
get
(
'command'
)
command_key
=
request
.
form
.
get
(
'command'
)
if
command_key
in
COMMANDS
:
if
config
.
has_section
(
'ACTION:'
+
command_key
):
result
=
run_command
(
COMMANDS
[
command_key
])
command
=
config
.
get
(
'ACTION:'
+
command_key
,
'execute'
,
fallback
=
None
)
if
command
:
result
=
run_command
(
command
)
else
:
return
"No command available"
return
result
return
result
else
:
else
:
return
"Invalid command"
,
400
return
"Invalid command"
,
400
...
...
templates/index.html
View file @
f189822b
...
@@ -107,22 +107,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
...
@@ -107,22 +107,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
transition
:
width
0.3s
ease
;
transition
:
width
0.3s
ease
;
}
}
.sidebar.expanded
~
.buttons-container
{
width
:
66.66vw
;
}
/* Button layout */
.button_row
{
.buttons-container
>
.button
{
display
:
grid
;
grid-column
:
span
3
;
grid-template-columns
:
repeat
(
12
,
1
fr
);
width
:
100%
;
grid-column
:
span
12
;
}
}
/* Third row layout */
{
{style_rows|safe
}
}
.buttons-container
>
.button
:nth-child
(
9
),
.buttons-container
>
.button
:nth-child
(
10
),
.sidebar.expanded
~
.buttons-container
{
.buttons-container
>
.button
:nth-child
(
11
)
{
width
:
66.66vw
;
grid-column
:
span
4
;
}
}
.button
{
.button
{
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
...
@@ -181,45 +180,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
...
@@ -181,45 +180,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<!-- Buttons Container -->
<!-- Buttons Container -->
<div
class=
"buttons-container"
>
<div
class=
"buttons-container"
>
<!-- Private Commands - Row 1 -->
{{htmlbuttons|safe}}
<button
class=
"button private"
onclick=
"executeCommand('private_stefy')"
>
PRIVATE STEFY
</button>
<button
class=
"button private"
onclick=
"executeCommand('private_leeloo')"
>
PRIVATE LEELOO
</button>
<button
class=
"button private"
onclick=
"executeCommand('private_jasmin')"
>
PRIVATE JASMIN
</button>
<button
class=
"button private"
onclick=
"executeCommand('private_other')"
>
PRIVATE OTHER
</button>
<!-- Toggle Commands - Row 2 -->
<button
class=
"button toggle"
onclick=
"executeCommand('toggle_stefy')"
>
OPEN/CLOSE STEFY
</button>
<button
class=
"button toggle"
onclick=
"executeCommand('toggle_leeloo')"
>
OPEN/CLOSE LEELOO
</button>
<button
class=
"button toggle"
onclick=
"executeCommand('toggle_jasmin')"
>
OPEN/CLOSE JASMIN
</button>
<button
class=
"button toggle"
onclick=
"executeCommand('toggle_others')"
>
OPEN/CLOSE OTHERS
</button>
<!-- Special Commands - Row 3 -->
<button
class=
"button special"
onclick=
"executeCommand('tease')"
>
TEASE
</button>
<button
class=
"button special"
onclick=
"executeCommand('tease_all')"
>
TEASE ALL
</button>
<button
class=
"button special"
onclick=
"executeCommand('open')"
>
OPEN
</button>
<div></div>
</div>
</div>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment