summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyo Nakamura <upa@haeena.net>2023-09-02 17:23:57 +0900
committerRyo Nakamura <upa@haeena.net>2023-09-02 17:23:57 +0900
commit49e8e26f2a82c7c6e8350f6ed748064b975c7788 (patch)
tree3918db8705f7ec41ec596f802856b32abc96e861
parent11e024c1dabb47b0a91e202f5a2068e0e5f7b299 (diff)
add jupyter example
ToDo: refactor state handling of pymscp
-rw-r--r--examples/.gitignore3
-rw-r--r--examples/mscp-example.ipynb226
-rw-r--r--mscp/mscp.py4
3 files changed, 233 insertions, 0 deletions
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..9cef686
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,3 @@
+simple-copy-dest
+*.img
+.ipynb_checkpoints
diff --git a/examples/mscp-example.ipynb b/examples/mscp-example.ipynb
new file mode 100644
index 0000000..915aeff
--- /dev/null
+++ b/examples/mscp-example.ipynb
@@ -0,0 +1,226 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "ccda9e3a-35de-43fc-9b6e-02475c763f6b",
+ "metadata": {},
+ "source": [
+ "# mscp python binding example"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 60,
+ "id": "df04d655-a082-47eb-9a1e-154ebc2a5655",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import glob\n",
+ "import time\n",
+ "import os\n",
+ "\n",
+ "import mscp"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "id": "e9ed4519-c3fd-4639-89a5-1c1cdffd9519",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "this_dir = os.getcwd()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fee75bf8-df40-45f4-81d1-113069c34f13",
+ "metadata": {},
+ "source": [
+ "## Simple copy"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "id": "2b06e6d3-30cc-47be-bd4f-af27eb141c8c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['../src/ssh.c',\n",
+ " '../src/mscp.c',\n",
+ " '../src/platform.c',\n",
+ " '../src/pymscp.c',\n",
+ " '../src/main.c',\n",
+ " '../src/path.c',\n",
+ " '../src/message.c',\n",
+ " '../src/fileops.c']"
+ ]
+ },
+ "execution_count": 54,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# preparing files to be transferred\n",
+ "c_sources = glob.glob(\"../src/*.c\")\n",
+ "c_sources"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "id": "89bb4558-9472-4d26-9af3-24f426b15edc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# copy files using mscp\n",
+ "dst_dir = this_dir + \"/simple-copy-dest\"\n",
+ "m = mscp.mscp(\"localhost\", mscp.LOCAL2REMOTE)\n",
+ "m.copy(c_sources, dst_dir)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "id": "6daf2c98-8905-4039-b82a-a593df3107fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['ssh.c',\n",
+ " 'mscp.c',\n",
+ " 'platform.c',\n",
+ " 'pymscp.c',\n",
+ " 'main.c',\n",
+ " 'path.c',\n",
+ " 'message.c',\n",
+ " 'fileops.c']"
+ ]
+ },
+ "execution_count": 56,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "os.listdir(\"simple-copy-dest\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f4a3869a-878e-43b0-9758-a049eaf8b5bd",
+ "metadata": {},
+ "source": [
+ "## Simple Copy with Python Rich ProgressBar"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 64,
+ "id": "e7cb7cd6-b845-4d26-93ed-aee8ed3983ab",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# make a 256MB file\n",
+ "src = \"example-256MB-src.img\"\n",
+ "with open(src, \"wb\") as f:\n",
+ " f.seek(128 * 1024 * 1024 -1, 0)\n",
+ " f.write(b'1')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "id": "878607ed-5c06-4b15-81ac-9845dad0c9c6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b700e9fc00464969a22a26300404dc35",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
+ "</pre>\n"
+ ],
+ "text/plain": [
+ "\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# copy the 256MB file while ploting progress bar using python rich\n",
+ "dst = this_dir + \"/example-256MB-dst.img\"\n",
+ "\n",
+ "kw = {\"nr_threads\": 1, \"nr_ahead\": 1} # slow mscp to watch the progress bar\n",
+ "\n",
+ "m = mscp.mscp(\"localhost\", mscp.LOCAL2REMOTE, **kw)\n",
+ "m.copy(src, dst, nonblock = True)\n",
+ "\n",
+ "# m.stats() returns total bytes to be transferred, bytes transferred (done), and finished (bool).\n",
+ "total, done, finished = m.stats()\n",
+ "with Progress() as progress:\n",
+ "\n",
+ " task = progress.add_task(f\"[green]Copying {src}\", total = total)\n",
+ "\n",
+ " while not progress.finished:\n",
+ " total, done, finished = m.stats()\n",
+ " progress.update(task, completed = done)\n",
+ " time.sleep(0.5)\n",
+ "\n",
+ "m.join()\n",
+ "m.cleanup()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.4"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/mscp/mscp.py b/mscp/mscp.py
index 05ff8b0..5804791 100644
--- a/mscp/mscp.py
+++ b/mscp/mscp.py
@@ -115,6 +115,8 @@ class mscp:
pymscp.mscp_set_dst_path(m = self.m, dst_path = dst_path);
def scan(self):
+ if self.state == STATE_SCANNED:
+ return
if self.state != STATE_CONNECTED:
raise RuntimeError("invalid mscp state: {}".format(self.__state2str()))
if not self.src_paths:
@@ -139,6 +141,8 @@ class mscp:
self.state = STATE_STOPPED
def join(self):
+ if self.state == STATE_JOINED:
+ return
if not (self.state == STATE_RUNNING or self.state == STATE_STOPPED):
raise RuntimeError("invalid mscp state: {}".format(self.__state2str()))
pymscp.mscp_join(m = self.m)