Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Distributed File System Explorer

Usage

Setup your Virtual Environment

On linux, run

$ python3 -m venv .venv

to create a virtual environment named .venv in the current directory.

Then, activate the virtual environment by running

$ source .venv/bin/activate

Configuration

A small number of server settings can be configured in src/config.py:

  • HOST - the host address the server will bind to.
  • PORT - the port the server will bind to.

Demo

  1. Launch the server by running src/app_server.py with Python 3.10

  2. Launch demo clients by running the following files with Python:

    • src/launch_test_client_1.py
    • src/launch_test_client_2.py
    • src/launch_test_client_3.py
  3. The server console with display instructions on how to query the connected clients.

Normal usage

  1. Launch the server by running src/app_server.py with Python
  2. Launch the clients by running python src/client_main.py <path_to_virtual_root>

Design

The server:

  • uses TCP/IP sockets to communicate with clients.
  • The starts by creating a listening socket.
  • The server handles multiple connections by using multiplexing with the select module.
  • For each client connection, the server creates a MessageHandler object to:
    • read variable length messages.
    • control the registration of the associated socket with the server's selector.

It was thought to be beneficial to allow the user to continue to input commands while the server waits on the client. This was achieved by using a non-blocking call to select.select() with a timeout of 1 second. After events from the selector have been handled, or the timeout has elapsed, the flow of the server returns to the user input dialog.

In all tests, the clients responded very quickly, so it would have looked nicer if the input halted until the client responded.

Clients:

Clients provide information of the virtual root folder that they point to. This virtual root folder is path that is pass to the client script when it is launched.

After a client connects, the client

  1. creates a MessageHandler object which handles the reading of variable length messages.
  2. then waits for a request from the server using a blocking call to .recv().
  3. responds to the server by sending information on the contents of a folder.

The server host and port can be configured in the src/config.py file.

Cavets

  • The server has not been tested with more than 5 simultaneous clients.
  • The client has not been designed to handle requests that match a file path. It handles directory paths only.

Assumptions

each client only connects to one server at a time

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages