Code Monkey home page Code Monkey logo

mousetracks's Introduction

Mouse Tracks

Current Status: I've got a full time job, so development on this has slowed. My plan is to start fresh with a much cleaner code base, where it'll be a lot more stable and modular than the current version.

Track and display mouse movements/clicks over time. Old movements will get faded so it can be left running indefinitely.

This was made with the intention of recording mouse movements over multiple resolutions then merging them together. It is used by loading (and forgetting about) start_tracking.py, and using generate_images.py to create the images. All the calculations are done in a background process, so that the tracking part will be able to run constantly without any CPU heavy calculations interfering with it.

By default, the tracking area is limited to the application window, but with no application detected, all monitors will be used, and merged over each other.

Current Features:

  • Track position, clicks, key presses and gamepad usage over multiple resolutions and monitors
  • Generate colourful mouse tracks and a heatmap of clicks or key presses (for everything or just the latest session)
  • Generate an image sequence of the last few hours of use
  • Fade old mouse tracks to keep recent tracks more visible
  • Record and adjust resolution based on the currently focused window
  • Automatically keep separate tracks for different applications (defined in "AppList.txt")
  • Perodically update AppList.txt from the internet, keeping and sorting all the old values, and adding any new ones
  • Edit settings with a config file, or by using the web based API
  • Full Windows support
  • Some Linux support (WIP)
  • Some Mac support (WIP)

Example Output:

Colour Maps:
Chalk:
Citrus:
Demon:
Sunburst:
Ice:
Hazard:
Spiderman:
Sketch:
Lightning:
Razer:
BlackWidow:
Grape:
Neon:
Shroud:

Game Genres:
Twin Stick:
FPS:
RTS:
MOBA:

Requirements:

  • Python 2.7 or 3.6 (written and tested in 2.7, but support for 3.6)
  • Numpy
  • psutil
  • scipy (required to generate images)
  • Pillow (required to generate images)
  • Flask (optional - used for the API)
  • PyCrypto (optional - encrypt API messages)
  • pyglet - included in code

Requirements (Windows):

  • pywin32 (optional - used for the tray icon)
  • xinput (required for gamepad tracking in Windows) - included in code

Requirements (Linux) (WIP):

Requirements (Mac) (WIP):

mousetracks's People

Contributors

haboutnnah avatar huntfx avatar peter92 avatar rubypwnz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mousetracks's Issues

Export raw data

Had a few requests for this, should be simple, just need to decide on how to format the data.

I'm thinking a CSV style text file for each separate resolution that has been recorded, I'm open to suggestions though.

Track inactivity time

The code exists to mark inactivity (to disable saving), but it could be adapted to track the time active/inactive, so it doesn't affect the overall track time, but gives more accurate stats.

Continue session when PID is the same

As well as starting a new session if the program is not loaded within a time, there should be an option to check the last few process IDs in case it's just been minimised for a few hours. Starting a new session will wipe the list of process IDs.

Detection happens after right click on taskbar preview

When hovering over an icon in the taskbar, it'll switch profile if the preview is right clicked, with a resolution of 160x28. Need to either delete maps for that particular resolution on load, or find a way to ignore it.

Minimise to system tray

To make it nicer for people running it a lot of the time, minimising should delete the icon from the taskbar and add it to the system tray

Track session length and discard if too short

I've found myself not wanting to load up things for a quick check of something while MT is running, as to not mess up the sessions. One potential fix would be to track session length, and discard it on the next profile load if certain conditions are met.

Don't allow unauthorized connections to the API

The point of the message server is to send the console output so that a GUI could display it for example. However, I just realised that will also be sending across the keystrokes, so it is at risk of being used by a keylogger if enabled.

I need some way of securing the connection, so that only an authorized client can make a connection. Not entirely sure what to do, but a workaround for the time being would be to request a code generated when the script started.

Folder names can trigger application tracking

The focus detection that uses application names also appears to activate if the explorer window is within the folder. I may have to redo the code for that.

Brief idea:
file.exe[window name]: game name
hl2.exe: Half-Life 2
hl2.exe[Portal]
hl2.exe[MyGame]: My Game

Questions regarding the workings/concept, possibilities and future plans

Haven't tested yet, but a question in forefront: What is the application like?

What i mean is:

Does it capture the mouse-coordinates per
a) Whole Desktop
b) per screen
c) per application Window

and whatever the answer(s) might be, why is it that way?

I am wondering for example if it would be possible to configure specific use-cases like track pointer of:

  • a remote-connection/VM via RDP/Spice and similar
  • a browser tab or a sub-window in a MDI app
  • a toolbox/window in a MDI/.Net app, for example a VST-Synth inside a DAW

Any hints on the inner workings would be wonderful.

Also, you mentioned you are working on a next version - any blog/changelog/issue-tracker one can follow?

Last question: How Python-specific is it - meaning are you using patterns/functions that are exclusive to Python or do you think it can be ported (halfway easily) to a Rust/WebAssembly/Node/Deno-Combo?

If you feel able to answer (some of) these questions it might be a good start for a wiki?

Gamepad/controller tracking

At some point I would like to add a support for controllers.

I had a look at inputs, but it pushes the CPU usage to max even when nothing is happening, so probably not the best choice in this case unless I can figure out why.

I have a big question

Where do u gather the information about the executable name and the application name ??

One important question

How can i access the data for my mouse movements and clicks?
And when i stars generate images script it says like below:

Select a profile by typing its name or the matching ID.
Files are being sorted by "last modified - descending".
Type "sort " to change or reverse the sorting method. Possible options are Creation Time (1), File Size (2), File Version (3), Last Modified (4), Session Count (5) and Track Length (6).

Page 1 of 0. Type "page " to switch.

Type your choice here: 1
Error: Invalid profile index: 1 (must be between 1-0)

Unicode characters cause crash when saving AppList.txt

I noticed AppList.txt wasn't updating, and found that it was unable to save due to unicode characters in the file. It's giving errors that I can't seem to replicate or fix, so I'll revisit it later.

For the time being until it's fixed I'll remove the offending line (蒼の彼方のフォーリズム.exe: Ao no Kanata no Four Rhythm), and avoid adding any similar ones.

Task groups

When I've been working on the website, I'm constantly switching between the browser and Dreamweaver, but anything I do outside of Dreamweaver gets recorded in the main tracks.

My idea is to add a grouped option, so you have the "Default" group, but can also set for example a "Python Coding" group, where if enabled, every data file will be saved with a prefix of pythoncoding_, or even a "Drunk Gaming" group, where you can compare your drunk and non drunk playstyles.

The code to list data files would need to be modified to ignore the prefix, and it can then ask the question of which group you want to generate.

API

Instead of tying a user interface straight into the code, a possibility would be to have an API running in the background, and it communicates with that instead, which would allow other services to interact too.

It should be able to accept input and relay the current status of the program, though before starting it'll be important to actually plan out what is needed, otherwise the code could need rewriting from scratch later down the line.

Something like send a request to localhost:12345/track/pause if you wanted to pause tracking.

From a quick google it appears using Flask to create a REST API may be the best way.

Error

Hello
I am completely excited about your project and would like to work with it. Unfortunately, I just can not get it to run. That's why I thought I'll ask the developer for help.
I would be very happy if you would like to work together.

I try to fix the problem on reddit but it does not work as well. https://redd.it/7vf5ud

That is what it looks like in the moment:
Launching a new console is not yet supported.
[02:57:31] Starting socket server... | Bound socket connection to port 52091. | Starting web server... | Bound web connection to port 52092. | The code required to connect to the message server is "63160f4b-0f53-459d-bdeb-56078c049de6".
[02:57:31] Set save location to "/Users/Mouse Tracks".
[02:57:31] Main process started.
[02:57:33] Background process started. | Finished loading data. | Unable to read cursor position.
[02:58:18] Background process quit. | Main process quit.

I hope you like to help me.

Save image periodically

An option should be there to generate a new image every x seconds. As it can be heavy on both RAM and CPU, it may have to run directly in the background thread so that there won't be multiple instances open at the same time.

Language options

Strings should be read from a file instead of being hardcoded, and the file could be determined in the config.

Auto set resolution

Instead of manually having to set the output resolution in config.ini, and auto option would be useful, as some games may be recorded at different aspects or lower resolutions.

In the case of recording at many different resolutions, I'm thinking it might be worth counting the total clicks for each resolution, finding what is the most popular aspect ratio, then finding what is the most popular resolution for that ratio.

Allow profiles to be switched in memory without loading/unloading

If I'm working with Visual Studio Code, the amount I switch in and out of it causes a backlog of tens of thousands commands. If you were to load it, type a sentence, then minimise, then it's got to save the "Default" profile, load the "Visual Studio Code" profile, record the sentence, save the "Visual Studio Code" profile, then load the "Default" profile. A lot of processing for a tiny amount of data.

Having some option for keeping a number of previous profiles loaded would be quite useful. The user could set a maximum amount based on available memory, then the program could determine if there are any profiles currently in use. This could be simply by keeping them loaded in memory for 10 minutes, or by detecting what is constantly getting loaded.

I'm thinking a wrapper class for saving and loading could work, though the saving would need a bit of a rework.

License

It would be much appreciated if a license was added. I propose the GPLv3, but obviously the owner can choose one.

It would ensure that no one will be legally harmed if they use the software or wish to modify it :)

Bind commands to keys for different profiles

I just came across a suggestion for having multiple Skyrim quicksaves that used AutoHotKey to intercept F5 and rename the old quicksave, before sending the keypress to the game.

Adding a part to run a command on keypress would certainly be possible, and would likely make a proper appearance once the GUI is added. As to intercepting keys, I'm not so sure if it would be possible, but I'll look into it.

Custom tracks per application

As the code to track different types of maps only contains a few minor differences, it would be possible to allow user defined ones.

The main issue would be how to integrate it within a file, but one option would be to only allow changes on file creation. and require the user to delete the file if they want to use new tracks. Alternatively, it should be possible write all "deleted" tracks to another file for a week or so, where re-enabling a certain track will read the saved data from the file. It avoids accidental deletions as well as file bloating. If that is done, it should run off the tracking options, and not a user set name.

Option Ideas:
Track [time/speed]
Limit to [all the time/when mouse [not] held (choose mouse buttons)/when key [not] held (choose key combinations)]
Compress [yes (with amount+max)/no]
Continuous [yes (draw all lines)/no (only draw if mouse moved in the last frame too)]

The default way is to track time with compression and continuous tracking. On the other hand, brush strokes is done by tracking speed, only when the mouse is held, without compression or continuous tracking. This would work for people using tablets to paint.

Change gaussian blur from a value to a multiplier

The gaussian blur option requires a specific value, but it can give different results depending on the resolution of the image.

The number appears to scale linearly with the horizontal resolution, so it's possible the number could be calculated to produce the same results no matter the resolution or aspect ratio.

The user could then provide a multiplier instead to tweak it to how they want, and not have to edit it if playing with the upscale resolution.

Invalid characters in AppList.txt cause regex crash

If a window name check contains a wildcard (so regex is used) and a question mark, then regex will throw an exception for an invalid expression. It's assuming the question mark is part of an expression when it isn't, so something will need to be done to escape the characters.

Only load required arrays

Instead of loading every resolution each time a different mtk file is loaded, a way of loading only what is required would reduce memory usage, and possibly speed up the overall load.

Generate images not showing anything?

For some reason when i go and click generate images the command window pops up, however there's no choices for me to select, even though I have it running.

Keyboard tracking doesn't work on certain applications

Using either ctypes or pywin32, the keyboard is not recognised when typing in certain applications. I've not been able to find a fix yet.

Steam is the main one I've found, where all games I've tested don't work, as well as the client itself.
Other launchers appear to work fine though, such as Battle.net, Bethesda and Epic Games, as well as custom ones like Guild Wars 2.

Render image using multiple cores

Converting the raw data to colours takes quite a while, so offloading it to available cores should be a considerable improvement. There should also be a config option to choose maximum number of cores allowed, where 0 is use all.

Don't quit background thread instantly

In the case there's still commands to process, the background thread should run until everything is finished.

This suggestion should work, but would potentially require quite a large rewrite. The main issue is I can't seem to open a new process after generating the exe with pyinstaller.

Can't you just run a second instance of Python using Popen? Queue is nothing but an unnamed pipe that transfers marshalled data. Just implement that yourself using a local TCP socket. Pass the port to the child, and send yourself pickled data.

Linux Support

The following functions are still needed for Linux (See here for details on each function):

get_monitor_locations

get_key_press

get_documents_path

read_env_var

Don't queue up more than a single save command

If the saving is set to 5 seconds for example, by the time one save is finished, there may have been another two queued up. This causes the script to get further and further behind where it'll never get a chance to catch up.

Keyboard output

Something similar to this might be worthwhile doing. Shouldn't be too hard, and I could link in my colour map code.

Steam Controller Support

The library I'm using for reading controllers doesn't support Steam controllers, so nothing will be picked up if playing with one of those.

There appear to be a few Python drivers, but they're mainly just built for Linux and aren't cross platform.

Add more optional variables to image name

When generating an image, the naming method is defined in the config. More variables should be added to give the user more control.

For example, Result\[FriendlyName] Heatmap - [MouseButtons] - [ColourProfile] ([UResX], [UResY]) could save an image in Result called Overwatch Heatmap - LMB+RMB - Citrus (1920, 1080).png

Current variables:

  • [FriendlyName]: Profile Name
  • [ResX]: Final Resolution X
  • [ResY]: Final Resolution Y
  • [UResX]: Upscale Resolution X
  • [UResY]: Upscale Resolution Y
  • [ColourProfile]: Colours Used
  • [ExpMult]: Exponential Multiplier (Heatmap)
  • [GaussianSize]: Gaussian Blur Size (Heatmap)
  • [MouseButtons]: Mouse Buttons Used (Heatmap) - results in Combined/[x]+[y]/[x]/Empty

Ideas:

  • [FileName]
  • [Modified]
  • [LastSaved]
  • [RunningTime]
  • [RunningTimeSeconds]
  • [RunningTimeTicks]
  • [Time]
  • [TimesLoaded]

Lazy load bypasses corrupt file check

Just came across this error after a crash:

Traceback (most recent call last):
  File "D:\Peter\Documents\Github\MouseTracks\core\track\background.py", line 357, in background_process
    record_mouse_move(store, received_data['MouseMove'])
  File "D:\Peter\Documents\Github\MouseTracks\core\track\background.py", line 688, in record_mouse_move
    store['Data']['Resolution'][resolution]['Tracks'][y][x] = store['Data']['Ticks']['Tracks']
  File "D:\Peter\Documents\Github\MouseTracks\core\numpy.py", line 278, in __getitem__
    return self.array[item]
  File "D:\Peter\Documents\Github\MouseTracks\core\numpy.py", line 274, in array
    self._array = self._load()
  File "D:\Peter\Documents\Github\MouseTracks\core\numpy.py", line 261, in _load
    return load(array)
  File "D:\Peter\Documents\Github\MouseTracks\core\numpy.py", line 232, in load
    return numpy.load(f)
  File "D:\Peter\Documents\Github\MouseTracks\env27\lib\site-packages\numpy\lib
pyio.py", line 443, in load
    "Failed to interpret file %s as a pickle" % repr(file))
IOError: Failed to interpret file <cStringIO.StringO object at 0x00000000132E0FB8> as a pickle

It appears the "lazy loading" module bypasses the corrupt file check. Potential fix would be to read the corrupt array from the backup file, but there may be issues if there's been any changes in resolution, so instead I may have to figure out how to discard the current data and load the previous. Alternatively some way of verifying the file was saved correctly would be useful.

Safe alternative for exchanging files

It's just come to my attention that cPickle is not particularly safe. I'll most likely keep it in use for its speed, but I'll have to include some sort of safer import/export function for sending things over the internet.

Reset held keys when switching profile

A trick I did in a game caused the computer to think a key was held down when it wasn't. I just noticed it carried on after quitting the game, affecting other profiles too. I've made a quick fix for it, but an ideal fix would be to reset the key held flags if a profile is switched.

Extra typing stats

The keyboard tracking is still quite basic, so could be expanded to record the time between keystrokes, and keystrokes per minute (and other things if they get suggested).

Image.ANTIALIAS python problem [Solved]

For anyone with problems generating images I just changed Image.ANTIALIAS to Image.LANCZOS in all instances inside moutracks/images/main.py.

I'm just creating the issue to announce this.

Take a look at this awesome result

180 Clicks (LMB) - Jet

Improved path options

Allow OS specific commands to be used in the path for file names.

An example would be %APPDATA% for windows, which is the same as C:\Users\[account]\AppData\Roaming.

Automatically set upscale resolution

After disabling the interpolation option, it appears higher upscale resolutions don't have a huge difference.

Instead of manually choosing the amount, it would be better to automatically pick the highest resolution, and possibly match it to the aspect ratio of the output image. For a small increase in quality, I'll add an option to double the resolution, but it'll be disabled by default.

Install/run?

Maybe I'm an idiot, but I can't figure out any information on how to install and/or run this program. There's no Releases, and I tried looking to see if there's an official website. I can't seem to find anything.

How does one run this on Windows?

Can't start tracking. KeyError: 'string'

I've been trying to get this working but no luck.

Traceback (most recent call last): File ".\start_tracking.py", line 4, in <module> from core.track import start_tracking File "C:\Users\keenjus\coding\python\MouseTracks\core\track\__init__.py", line 12, in <module> from core.notify import * File "C:\Users\keenjus\coding\python\MouseTracks\core\notify.py", line 340, in <module> NOTIFY = Notify() File "C:\Users\keenjus\coding\python\MouseTracks\core\notify.py", line 104, in __init__ self.string = all_strings['string']['track'] KeyError: 'string'

Am I missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.