Version 527

client is renamed hydrus_client. Lots of build lines to test here, so let's see how it goes
This commit is contained in:
Hydrus Network Developer 2023-05-09 16:56:03 -05:00
parent 7bfe474a5d
commit 5846b03e07
No known key found for this signature in database
GPG Key ID: 76249F053212133C
41 changed files with 521 additions and 115 deletions

View File

@ -110,22 +110,22 @@ jobs:
-
name: Remove Chonk
run: |
find dist/client/ -type f -name "*.pyc" -delete
while read line; do find dist/client/ -type f -name "${line}" -delete ; done < hydrus/static/build_files/linux/files_to_delete.txt
find dist/hydrus_client/ -type f -name "*.pyc" -delete
while read line; do find dist/hydrus_client/ -type f -name "${line}" -delete ; done < hydrus/static/build_files/linux/files_to_delete.txt
-
name: Remove Surplus File
run: |
rm -f dist/client/libxkbcommon.so*
rm -f dist/hydrus_client/libxkbcommon.so*
-
name: Set Permissions
run: |
sudo chown --recursive 1000:1000 dist/client
sudo find dist/client -type d -exec chmod 0755 {} \;
sudo chmod +x dist/client/client dist/client/server dist/client/bin/swfrender_linux
sudo find dist/hydrus_client -type d -exec chmod 0755 {} \;
sudo chmod +x dist/hydrus_client/client dist/hydrus_client/server dist/hydrus_client/bin/swfrender_linux
-
name: Compress Client
run: |
mv dist/client "dist/Hydrus Network"
mv dist/hydrus_client "dist/Hydrus Network"
tar -czvf Ubuntu-Extract.tar.gz -C dist "Hydrus Network"
-
name: Upload a Build Artifact
@ -187,10 +187,13 @@ jobs:
run: |
move hydrus\static\build_files\windows\sqlite3.dll hydrus\
move hydrus\static\build_files\windows\sqlite3.exe hydrus\db
move hydrus\static\build_files\windows\file_version_info_maker.py file_version_info_maker.py
python file_version_info_maker.py ${{ github.ref_name }}
move hydrus\static\build_files\windows\client-win.spec client-win.spec
move hydrus\static\build_files\windows\server-win.spec server-win.spec
pyinstaller server-win.spec
pyinstaller client-win.spec
move hydrus_client "Hydrus Network"
dir -r
-
# yo pretty sure we'll need to install this manually once we are on windows server 2022

3
.gitignore vendored
View File

@ -73,6 +73,9 @@ venv.bak/
/client-user.bat
/client-user.sh
/client-user.command
/hydrus_client-user.bat
/hydrus_client-user.sh
/hydrus_client-user.command
# docs builds
/site/

View File

@ -22,7 +22,7 @@ For a small database, this whole repair process may take an hour. For a larger,
Close the client immediately.
If you are on Windows, open task manager (Ctrl+Shift+Esc) and wait for client.exe to disappear from the list. If it takes more than a couple of minutes, forcibly close it with task manager.
If you are on Windows, open task manager (Ctrl+Shift+Esc) and wait for hydrus_client.exe to disappear from the list. If it takes more than a couple of minutes, forcibly close it with task manager.
*** check integrity ***

View File

@ -2,8 +2,8 @@ If your client seems to hang on the database startup phase, especially after a p
So, if your client seems suddenly to take a very long time to start up, just sitting on the splash screen, go make a coffee and give it time--it is probably just sorting itself out, not broken.
You can double-check this by looking at the client executable in your OS's Task Manager (Ctrl+Shift+Esc on Windows). If it is doing some CPU/HDD, there is no need to kill the process.
You can double-check this by looking at the hydrus_client executable in your OS's Task Manager (Ctrl+Shift+Esc on Windows). If it is doing some CPU/HDD, there is no need to kill the process.
Please contact hydrus_dev if it really does seem stuck (say, no progress after an hour, or if CPU/HDD activity completely drops to nothing for several minutes), or if every startup is delayed like this.
One possible cause of delayed startup every time (usually a delay _before_ the splash screen appears) is overly paranoid virus scanners rechecking all of hydrus every time it starts. To relieve this, please check your anti-virus software's options and make sure, if you have an HDD, that your disk is defragged.
One possible cause of delayed startup every time (usually a delay _before_ the splash screen appears) is overly paranoid virus scanners rechecking all of hydrus every time it starts. To relieve this, please check your anti-virus software's options and make sure, if you have an HDD, that your disk is defragged.

View File

@ -10,7 +10,7 @@ A hydrus client consists of three components:
1. **the software installation**
This is the part that comes with the installer or extract release, with the executable and dlls and a handful of resource folders. It doesn't store any of your settings--it just knows how to present a database as a nice application. If you just run the client executable straight, it looks in its 'db' subdirectory for a database, and if one is not found, it creates a new one. If it sees a database running at a lower version than itself, it will update the database before booting it.
This is the part that comes with the installer or extract release, with the executable and dlls and a handful of resource folders. It doesn't store any of your settings--it just knows how to present a database as a nice application. If you just run the hydrus_client executable straight, it looks in its 'db' subdirectory for a database, and if one is not found, it creates a new one. If it sees a database running at a lower version than itself, it will update the database before booting it.
It doesn't really matter where you put this. An SSD will load it marginally quicker the first time, but you probably won't notice. If you run it without command-line parameters, it will try to write to its own directory (to create the initial database), so if you mean to run it like that, it should not be in a protected place like _Program Files_.
@ -58,13 +58,13 @@ If you decide to move your actual database, the program will have to shut down f
## informing the software that the database is not in the default location { id="launch_parameter" }
A straight call to the client executable will look for a database in _install_dir/db_. If one is not found, it will create one. So, if you move your database and then try to run the client again, it will try to create a new empty database in the previous location!
A straight call to the hydrus_client executable will look for a database in _install_dir/db_. If one is not found, it will create one. So, if you move your database and then try to run the client again, it will try to create a new empty database in the previous location!
So, pass it a -d or --db_dir command line argument, like so:
* `client -d="D:\media\my_hydrus_database"`
* `hydrus_client -d="D:\media\my_hydrus_database"`
* _--or--_
* `client --db_dir="G:\misc documents\New Folder (3)\DO NOT ENTER"`
* `hydrus_client --db_dir="G:\misc documents\New Folder (3)\DO NOT ENTER"`
* _--or, for macOS--_
* `open -n -a "Hydrus Network.app" --args -d="/path/to/db"`
@ -102,7 +102,7 @@ Specifically:
* Hit 'move files now' again to make this happen. This should be fast since it is just moving a bunch of folders across the same partition.
* With everything now 'non-portable' and hence decoupled from the db, you can now easily migrate the install and db to 'hydrus_db' simply by shutting the client down and moving the install folder in a file explorer.
* Update your shortcut to the new client.exe location and try to boot.
* Update your shortcut to the new hydrus_client.exe location and try to boot.
* Update your backup scheme to match your new locations.
* Enjoy a much faster client.
@ -113,4 +113,4 @@ You should now have _something_ like this:
## p.s. running multiple clients { id="multiple_clients" }
Since you now know how to tell the software about an external database, you can, if you like, run multiple clients from the same install (and if you previously had multiple install folders, now you can now just use the one). Just make multiple shortcuts to the same client executable but with different database directories. They can run at the same time. You'll save yourself a little memory and update-hassle. I do this on my laptop client to run a regular client for my media and a separate 'admin' client to do PTR petitions and so on.
Since you now know how to tell the software about an external database, you can, if you like, run multiple clients from the same install (and if you previously had multiple install folders, now you can now just use the one). Just make multiple shortcuts to the same hydrus_client executable but with different database directories. They can run at the same time. You'll save yourself a little memory and update-hassle. I do this on my laptop client to run a regular client for my media and a separate 'admin' client to do PTR petitions and so on.

View File

@ -84,7 +84,7 @@ Hydrus is made by an Anon out of duct tape and string. It combines file parsing
Unfortunately, we have been hit by anti-virus false positives throughout development. Every few months, one or more of the larger anti-virus programs sees some code that looks like something bad, or they run the program in a testbed and don't like something it does, and then they quarantine it. Every single instance of this so far has been a false positive. They usually go away the next week or two when the next set of definitions roll out. Some hydrus users are kind enough to report the program as a false positive to the anti-virus companies themselves, which also helps here.
Some users have never had the problem, some get hit regularly. The situation is obviously worse on Windows. If you try to extract the zip and client.exe or the whole folder suddenly disappears, please check your anti-virus software.
Some users have never had the problem, some get hit regularly. The situation is obviously worse on Windows. If you try to extract the zip and hydrus_client.exe or the whole folder suddenly disappears, please check your anti-virus software.
I am interested in reports about these false-positives, just so I know what is going on. Sometimes I have been able to reduce problems by changing something in the build (one of these was, no shit, an anti-virus testbed running the installer and then opening the help html at the end, which launched Edge browser, which then triggered Windows Update, which hit UAC and was considered suspicious. I took out the 'open help' checkbox from the installer as a result).
@ -103,7 +103,7 @@ To run the client:
=== "Windows"
* For the installer, run the Start menu shortcut it added.
* For the extract, run 'client.exe' in the base directory, or make a shortcut to it.
* For the extract, run 'hydrus_client.exe' in the base directory, or make a shortcut to it.
=== "macOS"
@ -123,7 +123,17 @@ To run the client:
Although I put out a new version every week, you can update far less often if you prefer. The client keeps to itself, so if it does exactly what you want and a new version does nothing you care about, you can just leave it. Other users enjoy updating every week, simply because it makes for a nice schedule. Others like to stay a week or two behind what is current, just in case I mess up and cause a temporary bug in something they like.
A user has written a longer and more formal guide to updating, and information on the 334->335 step [here](update_guide.rtf).
A user has written a longer and more formal guide to updating, and information on the 334->335 step (python2 to python3) [here](update_guide.rtf).
??? note "The 526->527 step was also important."
527 changed the program executable name from 'client' to 'hydrus_client'. There was also a library update that caused a dll conflict with previous installs.
If you need to update from 526 or before, then:
* If you use the Windows installer, install as normal. Your start menu 'hydrus client' shortcut should be overwritten with one to the new executable, but if you use a custom shortcut, you will need to update that too.
* If you use one of the normal extract builds, you will have to do a 'clean install', as below. You also need to update your program shortcuts.
* If you use the macOS app, there are no special instructions. Update as normal.
* If you run from source, `git pull` as normal. If you haven't already, feel free to run setup_venv again to get the new OpenCV. Update your launch scripts to point at the new `hydrus_client.py` boot scripts.
The update process:

View File

@ -7,16 +7,16 @@ title: Launch Arguments
You can launch the program with several different arguments to alter core behaviour. If you are not familiar with this, you are essentially putting additional text after the launch command that runs the program. You can run this straight from a terminal console (usually good to test with), or you can bundle it into an easy shortcut that you only have to double-click. An example of a launch command with arguments:
```
C:\Hydrus Network\client.exe -d="E:\hydrus db" --no_db_temp_files
C:\Hydrus Network\hydrus_client.exe -d="E:\hydrus db" --no_db_temp_files
```
You can also add --help to your program path, like this:
- `client.py --help`
- `server.exe --help`
- `./server --help`
- `hydrus_client.py --help`
- `hydrus_server.exe --help`
- `./hydrus_server --help`
Which gives you a full listing of all below arguments, however this will not work with the built client executables, which are bundled as a non-console programs and will not give you text output to any console they are launched from. As client.exe is the most commonly run version of the program, here is the list, with some more help about each command:
Which gives you a full listing of all below arguments, however this will not work with the built hydrus_client executables, which are bundled as a non-console programs and will not give you text output to any console they are launched from. As hydrus_client.exe is the most commonly run version of the program, here is the list, with some more help about each command:
##**`-d DB_DIR, --db_dir DB_DIR`**

View File

@ -39,7 +39,7 @@ There are now setup scripts that make this easy on Windows and Linux. You do not
Then, get the hydrus source. The github repo is [https://github.com/hydrusnetwork/hydrus](https://github.com/hydrusnetwork/hydrus). If you are familiar with git, you can just clone the repo to the location you want with `git clone https://github.com/hydrusnetwork/hydrus`, but if not, then just go to the [latest release](https://github.com/hydrusnetwork/hydrus/releases/latest) and download and extract the source code .zip somewhere. Make sure the directory has write permissions (e.g. don't put it in "Program Files"). Extracting straight to a spare drive, something like "D:\Hydrus Network", is ideal.
We will call the base extract directory, the one with 'client.py' in it, `install_dir`.
We will call the base extract directory, the one with 'hydrus_client.py' in it, `install_dir`.
!!! info "Mixed Builds"
Don't mix and match build extracts and source extracts. The process that runs the code gets confused if there are unexpected extra .dlls in the directory. **If you need to convert between built and source releases, perform a [clean install](getting_started_installing.md#clean_installs).**
@ -222,7 +222,7 @@ _This is for advanced users only._
_If you have never used python before, do not try this. If the easy setup scripts failed for you and you don't know what happened, please contact hydev before trying this, as the thing that went wrong there will probably go much more wrong here._
You can also set up the environment yourself. Inside the extract should be client.py and server.py. You will be treating these basically the same as the 'client' and 'server' executables--with the right environment, you should be able to launch them the same way and they take the same launch parameters as the exes.
You can also set up the environment yourself. Inside the extract should be hydrus_client.py and hydrus_server.py. You will be treating these basically the same as the 'client' and 'server' executables--with the right environment, you should be able to launch them the same way and they take the same launch parameters as the exes.
Hydrus needs a whole bunch of libraries, so let's now set your python up. I **strongly** recommend you create a virtual environment. It is easy and doesn't mess up your system python.
@ -240,7 +240,7 @@ To create a new venv environment:
!!! info "venvs"
That `source venv/bin/activate` line turns on your venv. You should see your terminal prompt note you are now in it. A venv is an isolated environment of python that you can install modules to without worrying about breaking something system-wide. **Ideally, you do not want to install python modules to your system python.**
This activate line will be needed every time you alter your venv or run the `client.py`/`server.py` files. You can easily tuck this into a launch script--check the easy setup files for examples.
This activate line will be needed every time you alter your venv or run the `hydrus_client.py`/`hydrus_server.py` files. You can easily tuck this into a launch script--check the easy setup files for examples.
On Windows Powershell, the command is `.\venv\Scripts\activate`, but you may find the whole deal is done much easier in cmd than Powershell. When in Powershell, just type `cmd` to get an old fashioned command line. In cmd, the launch command is just `venv\scripts\activate.bat`, no leading period.
@ -311,11 +311,11 @@ If you don't have FFMPEG in your PATH and you want to import anything more fun t
### Running It { id="running_it" }
Once you have everything set up, client.py and server.py should look for and run off client.db and server.db just like the executables. You can use the 'client.bat/sh/command' scripts in the install dir or use them as inspiration for your own. In any case, you are looking at entering something like this into the terminal:
Once you have everything set up, hydrus_client.py and hydrus_server.py should look for and run off client.db and server.db just like the executables. You can use the 'client.bat/sh/command' scripts in the install dir or use them as inspiration for your own. In any case, you are looking at entering something like this into the terminal:
```
source venv/bin/activate
python client.py
python hydrus_client.py
```
This will use the 'db' directory for your database by default, but you can use the [launch arguments](launch_arguments.md) just like for the executables. For example, this could be your client-user.sh file:
@ -324,7 +324,7 @@ This will use the 'db' directory for your database by default, but you can use t
#!/bin/bash
source venv/bin/activate
python client.py -d="/path/to/database"
python hydrus_client.py -d="/path/to/database"
```
### Building these Docs

View File

@ -13,7 +13,7 @@ title: Running Your Own Server
I will use two terms, _server_ and _service_, to mean two distinct things:
* A **server** is an instantiation of the hydrus server executable (e.g. server.exe in Windows). It has a complicated and flexible database that can run many different services in parallel.
* A **server** is an instantiation of the hydrus server executable (e.g. hydrus_server.exe in Windows). It has a complicated and flexible database that can run many different services in parallel.
* A **service** sits on a port (e.g. 45871) and responds to certain http requests (e.g. `/file` or `/update`) that the hydrus client can plug into. A service might be a repository for a certain kind of data, the administration interface to manage what services run on a server, or anything else.
Setting up a hydrus server is easy compared to, say, Apache. There are no .conf files to mess about with, and everything is controlled through the client. When started, the server will place an icon in your system tray in Windows or open a small frame in Linux or macOS. To close the server, either right-click the system tray icon and select exit, or just close the frame.
@ -31,7 +31,7 @@ Let's look at these steps in more detail:
## start the server { id="start" }
Since the server and client have so much common code, I package them together. If you have the client, you have the server. If you installed in Windows, you can hit the shortcut in your start menu. Otherwise, go straight to 'server' or 'server.exe' or 'server.pyw' in your installation directory. The program will first try to take port 45870 for its administration interface, so make sure that is free. Open your firewall as appropriate.
Since the server and client have so much common code, I package them together. If you have the client, you have the server. If you installed in Windows, you can hit the shortcut in your start menu. Otherwise, go straight to 'hydrus_server' or 'hydrus_server.exe' or 'hydrus_server.py' in your installation directory. The program will first try to take port 45870 for its administration interface, so make sure that is free. Open your firewall as appropriate.
## set up the client { id="setting_up_the_client" }

View File

@ -3,7 +3,7 @@ title: You don't want the server
---
# You don't want the server
The server.exe/server.py is the victim of many a misconception. You don't need to use the server to use Hydrus. The vast majority of features are contained in the client itself so if you're new to Hydrus, just use that.
The hydrus_server.exe/hydrus_server.py is the victim of many a misconception. You don't need to use the server to use Hydrus. The vast majority of features are contained in the client itself so if you're new to Hydrus, just use that.
The server is only really useful for a few specific cases which will not apply for the vast majority of users.

View File

@ -1,4 +1,4 @@
If running the client executable does nothing or gives you an odd error before dumping out, here are some common fixes to try:
If running the hydrus_client executable does nothing or gives you an odd error before dumping out, here are some common fixes to try:
1. Look for a 'crash.log' in your 'db' directory or user desktop. Failing that, is there a 'client - [date].log' file? Does it have an error in it? If there is something, please send it in to me, hydrus_dev (see contact.html in the help directory for my contact details).
@ -12,4 +12,4 @@ Delete everything in your install directory except the 'db' directory. The 'db'
4. Check your permissions and hard drive health. For instance, sometimes when a hard drive has a fault, Windows sets it to 'dirty' mode, which causes all sorts of problems. Linux and OS X have presented their own permissions headaches. A default client works in 'portable' mode and needs read and write access to its 'db' folder.
5. Going forward, please consider making backups before you update the software. If a future update has a serious problem, it is then easy to rollback to the working version while we figure out a fix!
5. Going forward, please consider making backups before you update the software. If a future update has a serious problem, it is then easy to rollback to the working version while we figure out a fix!

View File

@ -187,6 +187,7 @@ MEDIA_VIEWER_ACTION_SHOW_OPEN_EXTERNALLY_BUTTON = 4
MEDIA_VIEWER_ACTION_DO_NOT_SHOW_ON_ACTIVATION_OPEN_EXTERNALLY = 5
MEDIA_VIEWER_ACTION_DO_NOT_SHOW = 6
MEDIA_VIEWER_ACTION_SHOW_WITH_MPV = 7
MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER = 8
media_viewer_action_string_lookup = {
MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE : 'show with native hydrus viewer',
@ -196,13 +197,14 @@ media_viewer_action_string_lookup = {
MEDIA_VIEWER_ACTION_SHOW_OPEN_EXTERNALLY_BUTTON : 'show an \'open externally\' button',
MEDIA_VIEWER_ACTION_DO_NOT_SHOW_ON_ACTIVATION_OPEN_EXTERNALLY : 'do not show in the media viewer. on thumbnail activation, open externally',
MEDIA_VIEWER_ACTION_DO_NOT_SHOW : 'do not show at all',
MEDIA_VIEWER_ACTION_SHOW_WITH_MPV : 'show using mpv'
MEDIA_VIEWER_ACTION_SHOW_WITH_MPV : 'show using mpv',
MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER : 'show using Qt Media Player (EXPERIMENTAL, buggy!)'
}
unsupported_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_OPEN_EXTERNALLY_BUTTON, MEDIA_VIEWER_ACTION_DO_NOT_SHOW_ON_ACTIVATION_OPEN_EXTERNALLY, MEDIA_VIEWER_ACTION_DO_NOT_SHOW ]
static_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE ] + unsupported_media_actions
animated_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_WITH_MPV ] + static_media_actions
audio_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_WITH_MPV ] + unsupported_media_actions
animated_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ] + static_media_actions
audio_media_actions = [ MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ] + unsupported_media_actions
# actions, can_start_paused, can_start_with_embed
static_full_support = ( static_media_actions, False, True )

View File

@ -1946,7 +1946,9 @@ class Controller( HydrusController.HydrusController ):
if True in ( service.GetPort() is not None for service in services ):
HydrusData.ShowText( 'Twisted failed to import, so could not start the local booru/client api! Please contact hydrus dev!' )
HydrusData.ShowText( 'Twisted failed to import, so could not start the local booru/client api! Specific error has been printed to log. Please contact hydrus dev!' )
HydrusData.Print( HG.twisted_is_broke_exception )
else:

View File

@ -6128,11 +6128,11 @@ class FrameGUI( CAC.ApplicationCommandProcessorMixin, ClientGUITopLevelWindows.M
if HC.PLATFORM_WINDOWS:
server_frozen_path = os.path.join( HC.BASE_DIR, 'server.exe' )
server_frozen_path = os.path.join( HC.BASE_DIR, 'hydrus_server.exe' )
else:
server_frozen_path = os.path.join( HC.BASE_DIR, 'server' )
server_frozen_path = os.path.join( HC.BASE_DIR, 'hydrus_server' )
if os.path.exists( server_frozen_path ):
@ -6143,9 +6143,9 @@ class FrameGUI( CAC.ApplicationCommandProcessorMixin, ClientGUITopLevelWindows.M
python_executable = sys.executable
if python_executable.endswith( 'client.exe' ) or python_executable.endswith( 'client' ):
if python_executable.endswith( 'hydrus_client.exe' ) or python_executable.endswith( 'hydrus_client' ):
raise Exception( 'Could not automatically set up the server--could not find server executable or python executable.' )
raise Exception( 'Could not automatically set up the server--could not find hydrus_client executable or python executable.' )
if 'pythonw' in python_executable:
@ -6153,7 +6153,7 @@ class FrameGUI( CAC.ApplicationCommandProcessorMixin, ClientGUITopLevelWindows.M
python_executable = python_executable.replace( 'pythonw', 'python' )
server_script_path = os.path.join( HC.BASE_DIR, 'server.py' )
server_script_path = os.path.join( HC.BASE_DIR, 'hydrus_server.py' )
cmd = [ python_executable, server_script_path, db_param ]

View File

@ -2920,11 +2920,16 @@ class EditMediaViewOptionsPanel( ClientGUIScrolledPanels.EditPanel ):
s = CC.media_viewer_action_string_lookup[ action ]
if action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV and self._mime in ( HC.IMAGE_GIF, HC.GENERAL_ANIMATION ):
if action in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ) and self._mime in ( HC.IMAGE_GIF, HC.GENERAL_ANIMATION ):
s += ' (will show unanimated gifs with native viewer)'
if action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE and self._mime in [ HC.GENERAL_VIDEO ] + list( HC.VIDEO ):
s += ' (no audio support)'
self._media_show_action.addItem( s, action )
if action != CC.MEDIA_VIEWER_ACTION_DO_NOT_SHOW_ON_ACTIVATION_OPEN_EXTERNALLY:
@ -3015,7 +3020,7 @@ class EditMediaViewOptionsPanel( ClientGUIScrolledPanels.EditPanel ):
QP.AddToLayout( vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
if set( possible_show_actions ).isdisjoint( { CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV } ):
if set( possible_show_actions ).isdisjoint( { CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER } ):
self._media_scale_up.hide()
self._media_scale_down.hide()

View File

@ -2263,7 +2263,7 @@ class ManageOptionsPanel( ClientGUIScrolledPanels.ManagePanel ):
pretty_preview_show_action += ', start with embed button'
no_show = { media_show_action, preview_show_action }.isdisjoint( { CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV } )
no_show = { media_show_action, preview_show_action }.isdisjoint( { CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER } )
if no_show:

View File

@ -4,6 +4,8 @@ import typing
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
from qtpy import QtMultimediaWidgets as QMW
from qtpy import QtMultimedia as QM
from hydrus.core import HydrusConstants as HC
from hydrus.core import HydrusData
@ -20,6 +22,7 @@ from hydrus.client.gui import ClientGUIFunctions
from hydrus.client.gui import ClientGUIMedia
from hydrus.client.gui import ClientGUIMediaControls
from hydrus.client.gui import ClientGUIShortcuts
from hydrus.client.gui import QtInit
from hydrus.client.gui import QtPorting as QP
from hydrus.client.gui.canvas import ClientGUIMPV
from hydrus.client.gui.widgets import ClientGUICommon
@ -308,7 +311,7 @@ def ShouldHaveAnimationBar( media, show_action ):
return False
if show_action not in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV ):
if show_action not in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ):
return False
@ -317,7 +320,7 @@ def ShouldHaveAnimationBar( media, show_action ):
is_audio = media.GetMime() in HC.AUDIO
is_video = media.GetMime() in HC.VIDEO
if show_action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV:
if show_action in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ):
if ( is_animated_image or is_audio or is_video ) and media.HasDuration():
@ -1162,7 +1165,7 @@ class AnimationBar( QW.QWidget ):
self._media_window.GotoFrame( current_frame_index )
elif isinstance( self._media_window, ClientGUIMPV.MPVWidget ):
elif isinstance( self._media_window, ( ClientGUIMPV.MPVWidget, QtMediaPlayer ) ):
time_index_ms = int( proportion * self._duration_ms )
@ -1448,7 +1451,7 @@ class MediaContainer( QW.QWidget ):
if media_window is not None:
launch_media_viewer_classes = ( Animation, ClientGUIMPV.MPVWidget, StaticImage )
launch_media_viewer_classes = ( Animation, ClientGUIMPV.MPVWidget, StaticImage, QtMediaPlayer )
media_window.removeEventFilter( self._additional_event_filter )
@ -1463,9 +1466,6 @@ class MediaContainer( QW.QWidget ):
pass # lmao, weird 'Failed to disconnect signal launchMediaViewer()' error I couldn't figure out, I guess some out-of-order deleteLater gubbins
if isinstance( media_window, launch_media_viewer_classes ):
media_window.ClearMedia()
if isinstance( media_window, StaticImage ):
@ -1480,6 +1480,11 @@ class MediaContainer( QW.QWidget ):
HG.client_controller.gui.ReleaseMPVWidget( media_window )
if isinstance( media_window, QtMediaPlayer ):
media_window.deleteLater()
else:
media_window.deleteLater()
@ -1489,7 +1494,7 @@ class MediaContainer( QW.QWidget ):
def _GetMaxZoomDimension( self ):
if self._show_action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV or isinstance( self._media_window, Animation ):
if self._show_action in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ) or isinstance( self._media_window, Animation ):
return 8000
@ -1513,7 +1518,14 @@ class MediaContainer( QW.QWidget ):
HydrusData.ShowText( 'MPV is not available!' )
if self._show_action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV and self._media.GetMime() == HC.IMAGE_GIF and not self._media.HasDuration():
if self._show_action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER and QtInit.WE_ARE_QT5:
self._show_action = CC.MEDIA_VIEWER_ACTION_SHOW_OPEN_EXTERNALLY_BUTTON
HydrusData.ShowText( 'Qt Media Player is only available on Qt6!' )
if self._show_action in ( CC.MEDIA_VIEWER_ACTION_SHOW_WITH_MPV, CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER ) and self._media.GetMime() == HC.IMAGE_GIF and not self._media.HasDuration():
self._show_action = CC.MEDIA_VIEWER_ACTION_SHOW_WITH_NATIVE
@ -1573,6 +1585,14 @@ class MediaContainer( QW.QWidget ):
self._media_window.lower()
elif self._show_action == CC.MEDIA_VIEWER_ACTION_SHOW_WITH_QMEDIAPLAYER:
self._media_window = QtMediaPlayer( self, self._canvas_type, self._background_colour_generator )
self._media_window.SetMedia( self._media, start_paused = self._start_paused )
self._media_window.lower()
if ShouldHaveAnimationBar( self._media, self._show_action ):
@ -1590,7 +1610,7 @@ class MediaContainer( QW.QWidget ):
self._media_window.installEventFilter( self._additional_event_filter )
launch_media_viewer_classes = ( Animation, ClientGUIMPV.MPVWidget, StaticImage )
launch_media_viewer_classes = ( Animation, ClientGUIMPV.MPVWidget, StaticImage, QtMediaPlayer )
if isinstance( self._media_window, launch_media_viewer_classes ):
@ -2888,6 +2908,278 @@ class OpenExternallyPanel( QW.QWidget ):
HydrusPaths.LaunchFile( path, launch_path )
class QtMediaPlayer( QW.QWidget ):
launchMediaViewer = QC.Signal()
def __init__( self, parent: QW.QWidget, canvas_type, background_colour_generator ):
QW.QWidget.__init__( self, parent )
self._canvas_type = canvas_type
self._background_colour_generator = background_colour_generator
self._my_audio_output = QM.QAudioOutput( self )
self._my_video_output = QMW.QVideoWidget( self )
self._my_audio_placeholder = QW.QWidget( self )
QP.SetBackgroundColour( self._my_audio_placeholder, QG.QColor( 0, 0, 0 ) )
# perhaps this stops the always on top behaviour, says several places, but it doesn't for me!
#self._my_video_output.setAttribute( QC.Qt.WA_TranslucentBackground, False )
self._media_player = QM.QMediaPlayer( self )
self._media_player.mediaStatusChanged.connect( self._MediaStatusChanged )
self._we_are_initialised = True
vbox = QP.VBoxLayout( margin = 0 )
QP.AddToLayout( vbox, self._my_video_output, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
QP.AddToLayout( vbox, self._my_audio_placeholder, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
self.setLayout( vbox )
self._media = None
self._playthrough_count = 0
if self._canvas_type in CC.CANVAS_MEDIA_VIEWER_TYPES:
shortcut_set = 'media_viewer_media_window'
else:
shortcut_set = 'preview_media_window'
self._my_shortcut_handler = ClientGUIShortcuts.ShortcutsHandler( self, [ shortcut_set ], catch_mouse = True )
def _MediaStatusChanged( self, status ):
if status == QM.QMediaPlayer.MediaStatus.EndOfMedia:
self._playthrough_count += 1
self._media_player.setPosition( 0 )
self._media_player.play()
def GetAnimationBarStatus( self ):
buffer_indices = None
if self._media is None:
current_frame_index = 0
current_timestamp_ms = 0
paused = True
else:
current_timestamp_ms = self._media_player.position()
num_frames = self._media.GetNumFrames()
if num_frames is None or num_frames == 1:
current_frame_index = 0
else:
current_frame_index = int( round( ( current_timestamp_ms / self._media.GetDurationMS() ) * num_frames ) )
current_frame_index = min( current_frame_index, num_frames - 1 )
current_timestamp_ms = min( current_timestamp_ms, self._media.GetDurationMS() )
paused = self.IsPaused()
return ( current_frame_index, current_timestamp_ms, paused, buffer_indices )
def ClearMedia( self ):
if self._media is not None:
self._media = None
# ok in my experience setting media_player.setSource to anything after a first load is pretty buggy!
# it can just straight up hang forever. either to a null QUrl or another file
# it seems to be it doesn't like unloading some files
# so, let's spawn a new one every time
# EDIT: ok going from one vid to another can cause crashes, so we are moving to a system where each QtMediaPlayer just gets one use. we'll make a new one every time
self._media_player.stop()
#self._media_player.setParent( None )
#QP.CallAfter( self._media_player.deleteLater )
#self._media_player = QM.QMediaPlayer( self )
#self._media_player.mediaStatusChanged.connect( self._MediaStatusChanged )
def HasPlayedOnceThrough( self ):
return self._playthrough_count > 0
def IsPaused( self ):
return not self._media_player.isPlaying()
def Pause( self ):
self._media_player.pause()
def PausePlay( self ):
if self.IsPaused():
self.Play()
else:
self.Pause()
def Play( self ):
self._media_player.play()
def ProcessApplicationCommand( self, command: CAC.ApplicationCommand ):
command_processed = True
if command.IsSimpleCommand():
action = command.GetSimpleAction()
if action == CAC.SIMPLE_PAUSE_MEDIA:
self.Pause()
elif action == CAC.SIMPLE_PAUSE_PLAY_MEDIA:
self.PausePlay()
elif action == CAC.SIMPLE_MEDIA_SEEK_DELTA:
( direction, duration_ms ) = command.GetSimpleData()
self.SeekDelta( direction, duration_ms )
elif action == CAC.SIMPLE_OPEN_FILE_IN_EXTERNAL_PROGRAM:
if self._media is not None:
self.Pause()
ClientGUIMedia.OpenExternally( self._media )
elif action == CAC.SIMPLE_CLOSE_MEDIA_VIEWER and self._canvas_type in CC.CANVAS_MEDIA_VIEWER_TYPES:
self.window().close()
elif action == CAC.SIMPLE_LAUNCH_MEDIA_VIEWER and self._canvas_type == CC.CANVAS_PREVIEW:
self.launchMediaViewer.emit()
else:
command_processed = False
else:
command_processed = False
return command_processed
def Seek( self, position_ms ):
self._media_player.setPosition( position_ms )
def SeekDelta( self, direction, duration_ms ):
if self._media is None:
return
current_timestamp_ms = self._media_player.position()
new_timestamp_ms = max( 0, current_timestamp_ms + ( direction * duration_ms ) )
if new_timestamp_ms > self._media.GetDurationMS():
new_timestamp_ms = 0
self.Seek( new_timestamp_ms )
def SetBackgroundColourGenerator( self, background_colour_generator ):
self._background_colour_generator = background_colour_generator
def SetMedia( self, media: ClientMedia.MediaSingleton, start_paused = False ):
if media == self._media:
return
self.ClearMedia()
self._media = media
has_audio = self._media.HasAudio()
is_audio = self._media.GetMime() in HC.AUDIO
if has_audio:
self._media_player.setAudioOutput( self._my_audio_output )
if not is_audio:
self._media_player.setVideoOutput( self._my_video_output )
self._my_video_output.setVisible( not is_audio )
self._my_audio_placeholder.setVisible( is_audio )
path = HG.client_controller.client_files_manager.GetFilePath( self._media.GetHash(), self._media.GetMime() )
self._media_player.setSource( QC.QUrl.fromLocalFile( path ) )
if not start_paused:
self._media_player.play()
class StaticImage( CAC.ApplicationCommandProcessorMixin, QW.QWidget ):
launchMediaViewer = QC.Signal()

View File

@ -100,7 +100,7 @@ options = {}
# Misc
NETWORK_VERSION = 20
SOFTWARE_VERSION = 526
SOFTWARE_VERSION = 527
CLIENT_API_VERSION = 44
SERVER_THUMBNAIL_DIMENSIONS = ( 200, 200 )

View File

@ -77,6 +77,7 @@ shutdown_complete = False
restart = False
twisted_is_broke = False
twisted_is_broke_exception = None
dirty_object_lock = threading.Lock()
client_busy = threading.Lock()

View File

@ -165,8 +165,11 @@ try:
from twisted.internet import reactor
except:
except Exception as e:
import traceback
HG.twisted_is_broke_exception = traceback.format_exc()
HG.twisted_is_broke = True

View File

@ -26,12 +26,12 @@ IF ERRORLEVEL 1 (
REM You can copy this file to 'client-user.bat' and add in your own launch parameters here if you like, and a git pull won't overwrite the file.
REM Just tack new params on like this:
REM start "" "pythonw" client.pyw -d="E:\hydrus"
REM start "" "pythonw" hydrus_client.pyw -d="E:\hydrus"
start "" "pythonw" client.pyw
start "" "pythonw" hydrus_client.pyw
REM Here is an alternate line that will keep the console open and see live log updates. Useful for boot/live debugging.
REM python client.py
REM Here is an alternate line that will keep the console open and show live log updates. Useful for boot/live debugging:
REM python hydrus_client.py
CALL venv\Scripts\deactivate.bat

View File

@ -14,11 +14,11 @@ if ! source venv/bin/activate; then
exit 1
fi
# You can copy this file to 'client-user.sh' and add in your own launch parameters here if you like, and a git pull won't overwrite the file.
# You can copy this file to 'hydrus_client-user.sh' and add in your own launch parameters here if you like, and a git pull won't overwrite the file.
# Just tack new params on like this:
# python client.py -d="/path/to/hydrus/db"
# python hydrus_client.py -d="/path/to/hydrus/db"
python client.py
python hydrus_client.py
deactivate

View File

@ -4,9 +4,9 @@
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
from hydrus import hydrus_test
from hydrus import hydrus_client_boot
if __name__ == '__main__':
hydrus_test.boot()
hydrus_client_boot.boot()

View File

@ -4,9 +4,9 @@
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
from hydrus import hydrus_client
from hydrus import hydrus_client_boot
if __name__ == '__main__':
hydrus_client.boot()
hydrus_client_boot.boot()

View File

@ -16,9 +16,9 @@ fi
# You can copy this file to 'client-user.sh' and add in your own launch parameters here if you like, and a git pull won't overwrite the file.
# Just tack new params on like this:
# python client.py -d="/path/to/hydrus/db"
# python hydrus_client.py -d="/path/to/hydrus/db"
python client.py
python hydrus_client.py
deactivate

4
client.pyw → hydrus_server.py Executable file → Normal file
View File

@ -4,9 +4,9 @@
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
from hydrus import hydrus_client
from hydrus import hydrus_server_boot
if __name__ == '__main__':
hydrus_client.boot()
hydrus_server_boot.boot()

View File

@ -4,9 +4,9 @@
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
from hydrus import hydrus_server
from hydrus import hydrus_test_boot
if __name__ == '__main__':
hydrus_server.boot()
hydrus_test_boot.boot()

View File

@ -7,22 +7,21 @@ cloudscraper_dir = os.path.dirname( cloudscraper.__file__ )
block_cipher = None
a = Analysis(['hydrus/client.py'],
a = Analysis(['hydrus/hydrus_client.py'],
pathex=['.'],
binaries=[],
datas=[
('hydrus/bin', 'bin'),
('hydrus/help', 'help'),
('hydrus/static', 'static'),
('dist/server/server', '.'),
('dist/hydrus_server/hydrus_server', '.'),
('hydrus/license.txt', '.'),
('hydrus/README.md', '.'),
('hydrus/help my client will not boot.txt', '.'),
('hydrus/db', 'db'),
('hydrus/hydrus', 'hydrus'),
(cloudscraper_dir, 'cloudscraper')
],
hiddenimports=['hydrus/server.py'],
hiddenimports=['hydrus/hydrus_server.py'],
hookspath=[],
runtime_hooks=[],
excludes=[],
@ -36,7 +35,7 @@ exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='client',
name='hydrus_client',
debug=False,
bootloader_ignore_signals=False,
strip=False,
@ -49,4 +48,4 @@ coll = COLLECT(exe,
strip=False,
upx=True,
upx_exclude=[],
name='client')
name='hydrus_client')

View File

@ -21,7 +21,7 @@ service-identity>=18.1.0
six>=1.14.0
Twisted>=20.3.0
opencv-python-headless==4.5.3.56
opencv-python-headless==4.5.5.64
python-mpv==0.5.2
QtPy==2.3.0
requests==2.28.1

View File

@ -3,7 +3,7 @@
block_cipher = None
a = Analysis(['hydrus/server.py'],
a = Analysis(['hydrus/hydrus_server.py'],
pathex=['.'],
binaries=[],
datas=[],
@ -21,7 +21,7 @@ exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='server',
name='hydrus_server',
debug=False,
bootloader_ignore_signals=False,
strip=False,
@ -33,4 +33,4 @@ coll = COLLECT(exe,
a.datas,
strip=False,
upx=True,
name='server')
name='hydrus_server')

View File

@ -15,10 +15,10 @@ def make_client(dist, policy):
python_config.module_search_paths = ["$ORIGIN", "$ORIGIN/lib"]
python_config.filesystem_importer = True
python_config.sys_frozen = True
python_config.run_command = "import os; import sys; exec(open(os.path.join(os.path.split(sys.executable)[0], 'client.py')).read())"
python_config.run_command = "import os; import sys; exec(open(os.path.join(os.path.split(sys.executable)[0], 'hydrus_client.py')).read())"
client = dist.to_python_executable(
name="client",
name="hydrus_client",
packaging_policy=policy,
config=python_config,
)
@ -37,9 +37,6 @@ def make_install(client, resources):
static_resources = glob(["./*.py", "./*.md", "./*txt", "./bin/**/*", "./static/**/*", "./help/**/*"], strip_prefix="{}/".format(CWD))
files.add_manifest(static_resources)
hydrus_source = glob(["./hydrus/**/*.py"], strip_prefix="{}/".format(CWD))
files.add_manifest(hydrus_source)
return files
print(BUILD_TARGET_TRIPLE)
@ -48,9 +45,9 @@ print(CWD)
# Tell PyOxidizer about the build targets defined above.
register_target("dist", make_dist)
register_target("policy", make_packaging_policy, depends=["dist"])
register_target("client", make_client, depends=["dist", "policy"])
register_target("resources", make_embedded_resources, depends=["client"], default_build_script=True)
register_target("install", make_install, depends=["client", "resources"], default=True)
register_target("hydrus_client", make_client, depends=["dist", "policy"])
register_target("resources", make_embedded_resources, depends=["hydrus_client"], default_build_script=True)
register_target("install", make_install, depends=["hydrus_client", "resources"], default=True)
resolve_targets()

View File

@ -21,7 +21,7 @@ service-identity>=18.1.0
six>=1.14.0
Twisted>=20.3.0
opencv-python-headless==4.5.3.56
opencv-python-headless==4.5.5.64
python-mpv==1.0.3
QtPy==2.2.1
requests==2.28.1

View File

@ -3,13 +3,13 @@
#endif
[Icons]
Name: {group}\hydrus client; Filename: {app}\client.exe; WorkingDir: {app}; Tasks: programgroupicons
Name: {group}\hydrus server; Filename: {app}\server.exe; WorkingDir: {app}; Tasks: programgroupicons
;Taking this out to stop anti-virus testbeds pursing it and launching Edge and detecting Edge update calls as suspicious DNS lmao
Name: {group}\hydrus client; Filename: {app}\hydrus_client.exe; WorkingDir: {app}; Tasks: programgroupicons
Name: {group}\hydrus server; Filename: {app}\hydrus_server.exe; WorkingDir: {app}; Tasks: programgroupicons
;Taking this out to stop anti-virus testbeds pursuing it and launching Edge and detecting Edge update calls as suspicious DNS lmao
;Name: {group}\help; Filename: {app}\help\index.html; WorkingDir: {app}; Tasks: programgroupicons
Name: {group}\uninstall hydrus network; Filename: {uninstallexe}; WorkingDir: {app}; Tasks: programgroupicons; IconFilename: {app}\static\cross.ico
Name: {userdesktop}\hydrus client; Filename: {app}\client.exe; WorkingDir: {app}; Tasks: desktopicons
Name: {userdesktop}\hydrus server; Filename: {app}\server.exe; WorkingDir: {app}; Tasks: desktopicons
Name: {userdesktop}\hydrus client; Filename: {app}\hydrus_client.exe; WorkingDir: {app}; Tasks: desktopicons
Name: {userdesktop}\hydrus server; Filename: {app}\hydrus_server.exe; WorkingDir: {app}; Tasks: desktopicons
[Setup]
InternalCompressLevel=ultra64
OutputDir=dist
@ -39,13 +39,14 @@ Name: install; Description: Install; Types: install; Flags: fixed
Name: install; Description: Install
Name: extract; Description: Extract only
[Run]
;Taking this out to stop anti-virus testbeds pursing it and launching Edge and detecting Edge update calls as suspicious DNS lmao
;Taking this out to stop anti-virus testbeds pursuing it and launching Edge and detecting Edge update calls as suspicious DNS lmao
;Filename: {app}\help\index.html; Description: Open help/getting started guide (highly recommended for new users); Flags: postinstall unchecked shellexec
Filename: {app}\client.exe; Description: Open the client; Flags: postinstall nowait unchecked
Filename: {app}\hydrus_client.exe; Description: Open the client; Flags: postinstall nowait unchecked
[Files]
Source: dist\Hydrus Network\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs
[InstallDelete]
Name: {app}\Crypto; Type: filesandordirs; Components: install
Name: {app}\cv2; Type: filesandordirs; Components: install
Name: {app}\tcl; Type: filesandordirs; Components: install
Name: {app}\tk; Type: filesandordirs; Components: install
Name: {app}\wx; Type: filesandordirs; Components: install
@ -57,6 +58,8 @@ Name: {app}\lib2to3; Type: filesandordirs; Components: install
Name: {app}\mpl-data; Type: filesandordirs; Components: install
Name: {app}\matplotlib; Type: filesandordirs; Components: install
Name: {app}\cryptography; Type: filesandordirs; Components: install
Name: {app}\client.exe; Type: files; Components: install
Name: {app}\server.exe; Type: files; Components: install
Name: {app}\opencv_ffmpeg344_64.dll; Type: files; Components: install
Name: {app}\opencv_ffmpeg400_64.dll; Type: files; Components: install
Name: {app}\opencv_ffmpeg410_64.dll; Type: files; Components: install

View File

@ -8,24 +8,24 @@ cloudscraper_dir = os.path.dirname( cloudscraper.__file__ )
block_cipher = None
a = Analysis(['hydrus\\client.pyw'],
a = Analysis(['hydrus\\hydrus_client.pyw'],
pathex=['.'],
binaries=[],
binaries=[
('hydrus\\sqlite3.dll', '.'),
('hydrus\\mpv-2.dll', '.')
],
datas=[
('hydrus\\bin', 'bin'),
('hydrus\\help', 'help'),
('hydrus\\static', 'static'),
('dist\\server\\server.exe*', '.'),
('dist\\hydrus_server\\hydrus_server.exe*', '.'),
('hydrus\\license.txt', '.'),
('hydrus\\README.md', '.'),
('hydrus\\help my client will not boot.txt', '.'),
('hydrus\\db', 'db'),
('hydrus\\hydrus', 'hydrus'),
('hydrus\\sqlite3.dll', '.'),
('hydrus\\mpv-2.dll', '.'),
(cloudscraper_dir, 'cloudscraper')
],
hiddenimports=['hydrus\\server.py', 'cloudscraper'],
hiddenimports=['hydrus\\hydrus_server.py', 'cloudscraper'],
hookspath=[],
runtime_hooks=[],
excludes=[],
@ -39,12 +39,13 @@ exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='client',
name='hydrus_client',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
console=False,
version_file='client_file_version_info.txt',
icon='hydrus\\static\\hydrus.ico' )
coll = COLLECT(exe,
a.binaries,
@ -53,4 +54,4 @@ coll = COLLECT(exe,
strip=False,
upx=False,
upx_exclude=[],
name='Hydrus Network')
name='hydrus_client')

View File

@ -0,0 +1,84 @@
import re
import sys
def string_generator( version, capitalised_name ):
match = re.match( r'^\d+', version )
if match:
version_number = int( match.group() )
else:
version_number = version
lower_name = capitalised_name.lower()
return f'''# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(0, {version_number}, 0, 0),
prodvers=(0, {version_number}, 0, 0),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
'040904b0',
[StringStruct('FileDescription', 'The Hydrus Network {capitalised_name}'),
StringStruct('FileVersion', '{version}'),
StringStruct('InternalName', 'Hydrus Network {capitalised_name}'),
StringStruct('LegalCopyright', 'WTFPL'),
StringStruct('OriginalFilename', 'hydrus_{lower_name}.exe'),
StringStruct('ProductName', 'Hydrus Network {capitalised_name}'),
StringStruct('ProductVersion', '{version}')])
]),
VarFileInfo([VarStruct('Translation', [1033, 1200])])
]
)'''
if __name__ == '__main__':
version_with_v = sys.argv[1]
if version_with_v.startswith( 'v' ):
version = version_with_v[1:]
else:
version = version_with_v
with open( 'client_file_version_info.txt', 'w', encoding = 'utf-8' ) as f:
f.write( string_generator( version, 'Client' ) )
with open( 'server_file_version_info.txt', 'w', encoding = 'utf-8' ) as f:
f.write( string_generator( version, 'Server' ) )

View File

@ -21,7 +21,7 @@ service-identity>=18.1.0
six>=1.14.0
Twisted>=20.3.0
opencv-python-headless==4.5.3.56
opencv-python-headless==4.5.5.64
python-mpv==1.0.3
QtPy==2.3.0
requests==2.28.1

View File

@ -3,7 +3,7 @@
block_cipher = None
a = Analysis(['hydrus\\server.py'],
a = Analysis(['hydrus\\hydrus_server.py'],
pathex=['.'],
binaries=[],
datas=[],
@ -21,12 +21,13 @@ exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='server',
name='hydrus_server',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
console=True,
version_file='server_file_version_info.txt',
icon='hydrus\\static\\hydrus.ico' )
coll = COLLECT(exe,
a.binaries,
@ -35,4 +36,4 @@ coll = COLLECT(exe,
strip=False,
upx=False,
upx_exclude=[],
name='server')
name='hydrus_server')