Skip to content

Commit 215a43a

Browse files
committed
Merge branch 'gh-pages' of https://github.com/LivelyKernel/lively4-core into gh-pages
2 parents 9e35050 + 6a0cd71 commit 215a43a

File tree

3 files changed

+226
-5
lines changed

3 files changed

+226
-5
lines changed

doc/journal/2021-02-09.md/index.md

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
## 2021-02-09 #DLF #Querkoepfe
2+
*Author: @JensLincke*
3+
4+
5+
## #Evolution #MarkdownApp #DirectorySpecificApplication
6+
7+
![](querkoepfe_rename_app.png)
8+
9+
<http://localhost:9005/Dropbox/Music/dlf/Querkoepfe/index.md>
10+
11+
(INFO: for this application to work, Lively4 does not have to be installed on localhost... Just a lively4 compatible file server, e.g. that can list (OPTIONS), GET, PUT, DELETE, and optionally MOVE files). In webwerkstatt (Lively2) we used apache webdav for it... our current protocol is custom.
12+
13+
An evening of scripting looked like this....
14+
15+
16+
| filename| date| user | host | size|
17+
|-------|---|--|---|--|
18+
| index.md | 22:10 | Bearbeitet von Jens Lincke | Desktop | 3,71 KB |
19+
| index.md | 22:01 | Bearbeitet von Jens Lincke | Desktop | 3,68 KB |
20+
| index.md | 21:56 | Bearbeitet von Jens Lincke | Desktop | 3,52 KB |
21+
| index.md | 21:54 | Bearbeitet von Jens Lincke | Desktop | 3,36 KB |
22+
| index.md | 21:51 | Bearbeitet von Jens Lincke | Desktop | 3,3 KB |
23+
| index.md | 21:48 | Bearbeitet von Jens Lincke | Desktop | 3,11 KB |
24+
| index.md | 21:47 | Bearbeitet von Jens Lincke | Desktop | 3,12 KB |
25+
| index.md | 21:43 | Bearbeitet von Jens Lincke | Desktop | 2,85 KB |
26+
| index.md | 21:42 | Bearbeitet von Jens Lincke | Desktop | 2,75 KB |
27+
| index.md | 21:40 | Bearbeitet von Jens Lincke | Desktop | 2,65 KB |
28+
| index.md | 21:33 | Bearbeitet von Jens Lincke | Desktop | 2,48 KB |
29+
| index.md | 21:30 | Bearbeitet von Jens Lincke | Desktop | 2,3 KB |
30+
| index.md | 21:29 | Bearbeitet von Jens Lincke | Desktop | 2,3 KB |
31+
| index.md | 21:19 | Bearbeitet von Jens Lincke | Desktop | 1,8 KB |
32+
| index.md | 21:17 | Bearbeitet von Jens Lincke | Desktop | 1,29 KB |
33+
| index.md | 21:15 | Bearbeitet von Jens Lincke | Desktop | 1,08 KB |
34+
| index.md | 21:14 | Bearbeitet von Jens Lincke | Desktop | 1,13 KB |
35+
| index.md | 21:12 | Bearbeitet von Jens Lincke | Desktop | 1,09 KB |
36+
| index.md | 21:08 | Bearbeitet von Jens Lincke | Desktop | 1.011 Bytes |
37+
| index.md | 21:06 | Bearbeitet von Jens Lincke | Desktop | 787 Bytes |
38+
| index.md | 21:04 | Bearbeitet von Jens Lincke | Desktop | 477 Bytes |
39+
| index.md | 21:01 | Bearbeitet von Jens Lincke | Desktop | 256 Bytes |
40+
| index.md | 20:59 | Bearbeitet von Jens Lincke | Desktop | 185 Bytes |
41+
| index.md | 20:57 | Hinzugefügt von Jens Lincke | Desktop | 15 Bytes |
42+
43+
44+
### Starting from a simple listing of files
45+
46+
47+
```javascript
48+
var container = lively.query(this, "lively-container") var dirURL = container.getDir()
49+
50+
var stats
51+
52+
(async () => { stats = await fetch(dirURL, {method: "OPTIONS"}).then(r => r.json())
53+
54+
return stats.contents })()
55+
```
56+
57+
### ... the script evolved in a bit over an hour into
58+
59+
```javascript
60+
61+
import Strings from 'src/client/strings.js'
62+
63+
class QuerkoepfeApp {
64+
65+
constructor(dirURL) {
66+
this.dirURL = dirURL
67+
}
68+
69+
70+
async loadDLFQuerkoepfe(isoDate) {
71+
var tab = await fetch(`http://localhost:9005/Dropbox/share/DLF/extract/${isoDate}.tab`).then(r => r.text())
72+
73+
var programm = tab.split(/\n/g).map(ea => ea.split(/\t/))
74+
75+
var querkoepfe = programm.filter(ea => ea[1] && ea[1].startsWith("Querköpfe"))[0]
76+
77+
programm.map(ea => ea[0])
78+
79+
80+
if (!querkoepfe || !querkoepfe[2]) return
81+
82+
var div = <div></div>
83+
div.innerHTML = querkoepfe[2]
84+
div.querySelector("p").innerHTML.split(/<br>/)
85+
return div.querySelector("p").innerHTML.split(/<br>/)
86+
87+
}
88+
89+
90+
91+
async selectItem(item) {
92+
if (this.lastSelected) this.lastSelected.classList.remove("selected")
93+
item.classList.add("selected")
94+
this.lastSelected = item
95+
96+
97+
var m = item.textContent.match(/(20\d\d-\d\d-\d\d)/)
98+
if (m) {
99+
var isoDate = m[1]
100+
} else {
101+
return
102+
}
103+
104+
var info = await this.loadDLFQuerkoepfe(isoDate)
105+
106+
if (!info) {
107+
this.details.innerHTML = "no details"
108+
} else {
109+
this.details.innerHTML = JSON.stringify(info)
110+
this.lastSelected.info = info
111+
}
112+
113+
}
114+
115+
onItemClick(evt, item) {
116+
117+
this.selectItem(item)
118+
119+
// if (item.classList.contains("selected")) {
120+
// item.classList.remove("selected")
121+
// } else {
122+
// item.classList.add("selected")
123+
// }
124+
}
125+
126+
async onRenameButton(evt) {
127+
if (!this.lastSelected || !this.lastSelected.info) return
128+
if (!this.lastSelected.file) return
129+
130+
var rawPattern = "Wed_2105_querkoepfe"
131+
132+
var filename = this.lastSelected.file.name
133+
if (!filename.match(rawPattern)) {
134+
lively.notify("file has already a custom name")
135+
return
136+
}
137+
138+
139+
var info = this.lastSelected.info
140+
var s ="Querkoepfe - " + info[1]
141+
if (info[2]) s += " - " + info[2]
142+
s = s.replace(/ /g, "_")
143+
s = s.replace(/[:.\/]/g, "_")
144+
145+
s = s.replace(/_+/g, "_")
146+
147+
var newFilename = filename.replace(rawPattern, s)
148+
149+
var fromURL = this.dirURL + encodeURI(filename)
150+
var toURL = this.dirURL + encodeURI(newFilename)
151+
152+
153+
await lively.confirm("rename " + filename + " -> " + newFilename + " in " + this.dirURL)
154+
155+
156+
var resp = await lively.files.moveFile(fromURL, toURL)
157+
if (resp.status == 200) {
158+
this.lastSelected.innerHTML = newFilename
159+
} else {
160+
this.lastSelected.style.backgroundColor = "red"
161+
}
162+
163+
// lively.warn("not implemented yet")
164+
165+
}
166+
async createView() {
167+
var stats = await fetch(this.dirURL, {method: "OPTIONS"}).then(r => r.json())
168+
169+
170+
var items = stats.contents
171+
.sortBy(ea => ea.name)
172+
.map(ea => {
173+
var item = <li>{ea.name}</li>
174+
item.file = ea
175+
item.addEventListener("click", evt => this.onItemClick(evt, item))
176+
return item
177+
})
178+
179+
var list = <ul id="list">{...items}</ul>
180+
var style = document.createElement("style") // #ISSUE style tags conflict with Markdown rewriting....
181+
style.innerHTML = `
182+
li.selected {
183+
background-color: lightgray
184+
}
185+
186+
#pane {
187+
height: 100%;
188+
}
189+
190+
#list {
191+
height: 400px;
192+
overflow: auto;
193+
}
194+
195+
`
196+
this.details = <div id="details"></div>
197+
return <div>
198+
{style}
199+
<div id="pane">
200+
<div id="buttons"><button click={evt => this.onRenameButton(evt)}>rename</button></div>
201+
{this.details}
202+
{list}
203+
</div>
204+
</div>
205+
}
206+
207+
}
208+
209+
210+
var container = lively.query(this, "lively-container")
211+
new QuerkoepfeApp(container.getDir()).createView()
212+
213+
```
214+
215+
I knew [the domain](https://lively-kernel.org/repository/webwerkstatt/users/jenslincke/DLF.xhtml), programmed similar applications before and could look at existing scripts when I ran into an issue with renaming umlauts. But this the (yet unpolished) typical kind of application I expect Lively4 users to build. Some parts of the overall application is handled outside of lively, e.g. the recording of the radio show and the downloading (and parsing) of the radio program and information. Since both approaches are long running and require full web access. Downloading and scraping other websites would is prevented by the browser and requires Lively additional help from a proxy server or in this case a shell script.
216+
217+
The resulting Lively4 is a markdown file that is persisted beside the data (mp3 files) it works on. When browsing the directory of the files within lively will show "index.md" file and run the application. In a funny way, this is a context specific application inside a directory... I think Windows Explorer experimented with such "Active Desktop" in the 90ies... But the time was not right yet and everybody hated it, because it slowed down the computer. And I assume was a huge security risk. Which might be the same for this application...
218+
219+
482 KB
Loading

src/client/files.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,15 @@ export default class Files {
151151
if (fromServerURL && (fromServerURL == toServerURL)) {
152152

153153
// use special server MOVE/RENAME method
154-
var result = await fetch(url, {
154+
var resp = await fetch(url, {
155155
method: "MOVE",
156156
headers: {
157157
destination: newURL
158158
}
159-
}).then(r => r.text())
159+
})
160+
var result = await resp.text()
160161
lively.notify("MOVE", result)
161-
return
162+
return resp
162163
}
163164

164165
var content = await fetch(url).then(r => r.blob())
@@ -171,7 +172,7 @@ export default class Files {
171172

172173
if (putResponse.status !== 200) {
173174
lively.confirm("could not move file to " + newURL)
174-
return
175+
return putResponse
175176
}
176177

177178
// ok, lets be crazy... we first delete
@@ -187,8 +188,9 @@ export default class Files {
187188
method: 'PUT',
188189
body: content
189190
})
190-
return
191+
return putAgainResponse
191192
}
193+
return getResponse
192194
}
193195

194196
static async statFile(urlString){

0 commit comments

Comments
 (0)