Skip to content

Commit 3aa5f60

Browse files
committed
Merge remote-tracking branch 'adafruit/main' into upload_folder
2 parents 9a5f00a + 2f0e209 commit 3aa5f60

File tree

11 files changed

+206
-66
lines changed

11 files changed

+206
-66
lines changed

docs/workflows.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,24 @@ Example:
202202
curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
203203
```
204204

205+
##### Move
206+
Moves the directory at the given path to ``X-Destination``. Also known as rename.
207+
208+
The custom `X-Destination` header stores the destination path of the directory.
209+
210+
* `201 Created` - Directory renamed
211+
* `401 Unauthorized` - Incorrect password
212+
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
213+
* `404 Not Found` - Source directory not found or destination path is missing
214+
* `409 Conflict` - USB is active and preventing file system modification
215+
* `412 Precondition Failed` - The destination path is already in use
216+
217+
Example:
218+
219+
```sh
220+
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello2/" -L --location-trusted http://circuitpython.local/fs/lib/hello/
221+
```
222+
205223
##### DELETE
206224
Deletes the directory and all of its contents.
207225

@@ -214,7 +232,7 @@ Deletes the directory and all of its contents.
214232
Example:
215233

216234
```sh
217-
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
235+
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello2/world/
218236
```
219237

220238

@@ -270,6 +288,25 @@ curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hel
270288
```
271289

272290

291+
##### Move
292+
Moves the file at the given path to the ``X-Destination``. Also known as rename.
293+
294+
The custom `X-Destination` header stores the destination path of the file.
295+
296+
* `201 Created` - File renamed
297+
* `401 Unauthorized` - Incorrect password
298+
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
299+
* `404 Not Found` - Source file not found or destination path is missing
300+
* `409 Conflict` - USB is active and preventing file system modification
301+
* `412 Precondition Failed` - The destination path is already in use
302+
303+
Example:
304+
305+
```sh
306+
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello/world2.txt" -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
307+
```
308+
309+
273310
##### DELETE
274311
Deletes the file.
275312

@@ -283,7 +320,7 @@ Deletes the file.
283320
Example:
284321

285322
```sh
286-
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
323+
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world2.txt
287324
```
288325

289326
### `/cp/`

ports/espressif/common-hal/touchio/TouchIn.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,38 +30,22 @@
3030
#include "peripherals/touch.h"
3131
#include "shared-bindings/microcontroller/Pin.h"
3232

33-
static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
34-
#if defined(CONFIG_IDF_TARGET_ESP32)
35-
uint16_t touch_value;
36-
#else
37-
uint32_t touch_value;
38-
#endif;
39-
touch_pad_read_raw_data(self->pin->touch_channel, &touch_value);
40-
if (touch_value > UINT16_MAX) {
41-
return UINT16_MAX;
42-
}
43-
return (uint16_t)touch_value;
44-
}
45-
4633
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
4734
const mcu_pin_obj_t *pin) {
48-
if (pin->touch_channel == TOUCH_PAD_MAX) {
35+
if (pin->touch_channel == NO_TOUCH_CHANNEL) {
4936
raise_ValueError_invalid_pin();
5037
}
5138
claim_pin(pin);
5239

5340
// initialize touchpad
5441
peripherals_touch_init(pin->touch_channel);
5542

56-
// wait for touch data to reset
57-
mp_hal_delay_ms(10);
58-
5943
// Set a "touched" threshold not too far above the initial value.
6044
// For simple finger touch, the values may vary as much as a factor of two,
6145
// but for touches using fruit or other objects, the difference is much less.
6246

6347
self->pin = pin;
64-
self->threshold = get_raw_reading(self) + 100;
48+
self->threshold = common_hal_touchio_touchin_get_raw_value(self) + 100;
6549
}
6650

6751
bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self) {
@@ -77,11 +61,11 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self) {
7761
}
7862

7963
bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) {
80-
return get_raw_reading(self) > self->threshold;
64+
return common_hal_touchio_touchin_get_raw_value(self) > self->threshold;
8165
}
8266

8367
uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) {
84-
return get_raw_reading(self);
68+
return peripherals_touch_read(self->pin->touch_channel);
8569
}
8670

8771
uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) {

ports/espressif/peripherals/touch.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void peripherals_touch_never_reset(const bool enable) {
4343
void peripherals_touch_init(const touch_pad_t touchpad) {
4444
if (!touch_inited) {
4545
touch_pad_init();
46-
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
46+
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW);
4747
}
4848
// touch_pad_config() must be done before touch_pad_fsm_start() the first time.
4949
// Otherwise the calibration is wrong and we get maximum raw values if there is
@@ -52,13 +52,27 @@ void peripherals_touch_init(const touch_pad_t touchpad) {
5252
touch_pad_config(touchpad, 0);
5353
#else
5454
touch_pad_config(touchpad);
55+
touch_pad_fsm_start();
5556
#endif
56-
if (!touch_inited) {
57-
#if defined(CONFIG_IDF_TARGET_ESP32)
58-
touch_pad_sw_start();
59-
#else
60-
touch_pad_fsm_start();
61-
#endif
62-
touch_inited = true;
57+
touch_inited = true;
58+
}
59+
60+
uint16_t peripherals_touch_read(touch_pad_t touchpad) {
61+
#if defined(CONFIG_IDF_TARGET_ESP32)
62+
uint16_t touch_value;
63+
touch_pad_read(touchpad, &touch_value);
64+
// ESP32 touch_pad_read() returns a lower value when a pin is touched instead of a higher value.
65+
// Flip the values around to be consistent with TouchIn assumptions.
66+
return UINT16_MAX - touch_value;
67+
#else
68+
uint32_t touch_value;
69+
touch_pad_sw_start();
70+
while (!touch_pad_meas_is_done()) {
71+
}
72+
touch_pad_read_raw_data(touchpad, &touch_value);
73+
if (touch_value > UINT16_MAX) {
74+
return UINT16_MAX;
6375
}
76+
return (uint16_t)touch_value;
77+
#endif
6478
}

ports/espressif/peripherals/touch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include "driver/touch_pad.h"
3131

32+
extern uint16_t peripherals_touch_read(touch_pad_t touchpad);
3233
extern void peripherals_touch_reset(void);
3334
extern void peripherals_touch_never_reset(const bool enable);
3435
extern void peripherals_touch_init(const touch_pad_t touchpad);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Online Code Editor</title>
7+
</head>
8+
9+
<body>
10+
<script type="module" src="https://code.circuitpython.org/assets/js/device.js"></script>
11+
</body>
12+
</html>

supervisor/shared/web_workflow/static/directory.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<body>
1111
<h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;<span id="path"></span></h1>
1212
<div id="usbwarning" style="display: none;">ℹ️ USB is using the storage. Only allowing reads. See <a href="https://learn.adafruit.com/circuitpython-essentials/circuitpython-storage">the CircuitPython Essentials: Storage guide</a> for details.</div>
13-
<template id="row"><tr><td></td><td></td><td><a></a></td><td></td><td><button class="delete">🗑️</button></td><td><a class="edit_link" href="">Edit</a></td></tr></template>
13+
<template id="row"><tr><td></td><td></td><td><a class="path"></a></td><td class="modtime"></td><td><button class="rename">✏️ Rename</button></td><td><button class="delete">🗑️ Delete</button></td><td><a class="edit_link" href=""><button>📝 Edit</button></a></td></tr></template>
1414
<table>
15-
<thead><tr><th>Type</th><th>Size</th><th>Path</th><th>Modified</th><th></th></tr></thead>
15+
<thead><tr><th>Type</th><th>Size</th><th>Path</th><th>Modified</th><th colspan="3"></th></tr></thead>
1616
<tbody></tbody>
1717
</table>
1818
<hr>

supervisor/shared/web_workflow/static/directory.js

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,22 @@ var url_base = window.location;
66
var current_path;
77
var editable = undefined;
88

9+
function compareValues(a, b) {
10+
if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) {
11+
return 0;
12+
} else if (a.directory != b.directory) {
13+
return a.directory < b.directory ? 1 : -1;
14+
} else {
15+
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
16+
}
17+
}
18+
919
function set_upload_enabled(enabled) {
1020
files.disabled = !enabled;
1121
dirs.disabled = !enabled;
1222
}
1323

1424
async function refresh_list() {
15-
16-
function compareValues(a, b) {
17-
if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) {
18-
return 0;
19-
} else {
20-
return a.directory.toString().substring(3,4)+a.name.toLowerCase() < b.directory.toString().substring(3,4)+b.name.toLowerCase() ? -1 : 1;
21-
}
22-
}
23-
2425
current_path = window.location.hash.substr(1);
2526
if (current_path == "") {
2627
current_path = "/";
@@ -58,7 +59,7 @@ async function refresh_list() {
5859
}
5960
}
6061

61-
if (window.location.path != "/fs/") {
62+
if (current_path != "/") {
6263
var clone = template.content.cloneNode(true);
6364
var td = clone.querySelectorAll("td");
6465
td[0].textContent = "📁";
@@ -68,6 +69,8 @@ async function refresh_list() {
6869
path.textContent = "..";
6970
// Remove the delete button
7071
td[4].replaceChildren();
72+
td[5].replaceChildren();
73+
td[6].replaceChildren();
7174
new_children.push(clone);
7275
}
7376

@@ -88,31 +91,46 @@ async function refresh_list() {
8891
file_path = api_url;
8992
}
9093

94+
var text_file = false;
9195
if (f.directory) {
9296
icon = "📁";
9397
} else if(f.name.endsWith(".txt") ||
98+
f.name.endsWith(".env") ||
9499
f.name.endsWith(".py") ||
95100
f.name.endsWith(".js") ||
96101
f.name.endsWith(".json")) {
97102
icon = "📄";
103+
text_file = true;
98104
} else if (f.name.endsWith(".html")) {
99105
icon = "🌐";
106+
text_file = true;
100107
}
101108
td[0].textContent = icon;
102109
td[1].textContent = f.file_size;
103-
var path = clone.querySelector("a");
110+
var path = clone.querySelector("a.path");
104111
path.href = file_path;
105112
path.textContent = f.name;
106-
td[3].textContent = (new Date(f.modified_ns / 1000000)).toLocaleString();
113+
let modtime = clone.querySelector("td.modtime");
114+
modtime.textContent = (new Date(f.modified_ns / 1000000)).toLocaleString();
107115
var delete_button = clone.querySelector("button.delete");
108116
delete_button.value = api_url;
109117
delete_button.disabled = !editable;
110118
delete_button.onclick = del;
111119

112-
if (editable && !f.directory) {
120+
121+
var rename_button = clone.querySelector("button.rename");
122+
rename_button.value = api_url;
123+
rename_button.disabled = !editable;
124+
rename_button.onclick = rename;
125+
126+
let edit_link = clone.querySelector(".edit_link");
127+
if (text_file && editable && !f.directory) {
113128
edit_url = new URL(edit_url, url_base);
114-
let edit_link = clone.querySelector(".edit_link");
115129
edit_link.href = edit_url
130+
} else if (f.directory) {
131+
edit_link.style = "display: none;";
132+
} else {
133+
edit_link.querySelector("button").disabled = true;
116134
}
117135

118136
new_children.push(clone);
@@ -214,6 +232,26 @@ async function del(e) {
214232
}
215233
}
216234

235+
async function rename(e) {
236+
let fn = new URL(e.target.value);
237+
var new_fn = prompt("Rename to ", fn.pathname.substr(3));
238+
if (new_fn === null) {
239+
return;
240+
}
241+
let new_uri = new URL("/fs" + new_fn, fn);
242+
const response = await fetch(e.target.value,
243+
{
244+
method: "MOVE",
245+
headers: {
246+
'X-Destination': new_uri.pathname,
247+
},
248+
}
249+
)
250+
if (response.ok) {
251+
refresh_list();
252+
}
253+
}
254+
217255
find_devices();
218256

219257
let mkdir_button = document.getElementById("mkdir");

supervisor/shared/web_workflow/static/edit.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
5-
<title>Code Edit</title>
5+
<title>Offline Code Edit</title>
66
<link rel="stylesheet" href="http://circuitpython.org/assets/css/webworkflow-8.css">
77
<link rel="stylesheet" href="/style.css">
88
</head>

supervisor/shared/web_workflow/static/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ body {
1717
margin: 0;
1818
font-size: 0.7em;
1919
}
20+
21+
:disabled {
22+
filter: saturate(0%);
23+
}

supervisor/shared/web_workflow/static/welcome.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var url_base = window.location;
22
var current_path;
33

4-
var mdns_works = window.location.hostname.endsWith(".local");
4+
var mdns_works = url_base.hostname.endsWith(".local");
55

66
async function find_devices() {
77
var version_response = await fetch("/cp/version.json");

0 commit comments

Comments
 (0)