-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathfile-export.qml
207 lines (174 loc) · 7.63 KB
/
file-export.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import QtQml 2.0
import com.qownnotes.noteapi 1.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button to export attachments and media from the note.
* Select the text with the markdown links you want to export or nothing for all files inside the note.
* It will automatically used the correct file names of the note (not the scrambled number inside the attachments folder) and create a zipped file if more the one file is selected (Linux only for now).
* You can also format selected attachments neatly with the format button or context menu.
*/
QtObject {
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
];
function log(text){
script.log("[FileExport] "+text)
}
property var dialog
function exportFiles() {
log("Exporting files ...")
if (!script.platformIsLinux()) {
// only will be executed if under Linux
script.informationMessageBox("The script does only support Linux.", "OS not supported");
return
}
//log("start")
const regex_media = /\[.+?\]\(.+?\)/gm;
const regex_name = /\[(.*?]*)\]/gm;
const regex_path = /\((.*?]*)\)/gm;
const selectedText = script.noteTextEditSelectedText()
if(selectedText === null || selectedText.length === 0){
return // TODO
}
const mdFiles = selectedText.match(regex_media)// regex_media.exec(selectedText)
if(mdFiles === null || mdFiles.length === 0){
return
}
const currentNote = script.currentNote();
if(currentNote === null){
script.informationMessageBox("Cannot access current note", "Note not found");
return
}
const folder = currentNote.fullNoteFileDirPath
var files = []
mdFiles.forEach(function(element, i, array){
// get the name with brackets
var name = element.match(regex_name)[0]// [name.pdf](../attachments/1234.svg)
// remove brackets
name = name.substring(1, name.length - 1) //removes last character
var filePath = element.match(regex_path)[0]
// remove brackets
filePath = filePath.substring(1, filePath.length - 1)
var path = folder+'/'+filePath
var file = [name, path]
files.push(file)
})
var para = []
var target
var cmd
if(files.length === 1){
cmd = "cp"
var suffix = getSuffix(files[0][1])
target = script.getSaveFileName("Please select a destination to save", files[0][0], "*"+suffix);
if(target === null || target === ''){
return // canceled
}
target += (target.endsWith(suffix) ? '' : suffix)
var source = files[0][1]
para.push(source)
para.push(target)
}else{
cmd = "zip"
para.push("-j") // no parent folders, _J_UST the files
target = script.getSaveFileName("Please select a destination to save", "QON_"+getDateString(), "zip (*.zip)");
if(target === null || target === ''){
return // canceled
}
para.push(target)
const tmpDir = "/tmp/qon/"+Date.now()+"/"
script.startSynchronousProcess("mkdir", ["-p",tmpDir]);
var tmpPara;
files.forEach(function(element, i, array){
var name = element[0]
var path = element[1]
var suffix = getSuffix(path)
// attachment names already carry the suffix [FileExport.qml](../attachments/FileExport-1357526733.qml)
var tmpPath = tmpDir+name+(name.endsWith(suffix) ? '' : suffix)
//create symlinks to allow the right file names to be zipped (ln -s wrong_name.txt right_name.txt)
tmpPara = []
tmpPara.push("-s")
tmpPara.push(path)
tmpPara.push(tmpPath)
script.startSynchronousProcess("ln", tmpPara) // Why doesn't ["-s", path, tmpPara] work?
para.push(tmpPath)
})
tmpPara = []
tmpPara.push("-r")
tmpPara.push(tmpDir)
}
var result = script.startSynchronousProcess(cmd, para); //startSynchronousProcess startDetachedProcess
// remove the temporary soft links
script.startSynchronousProcess("rm", tmpPara)
log("Exported file(s) to: "+target)
}
/**
*
*/
function getSuffix(filepath){
const regex_suffix = /\.[0-9a-z]+$/i;
return filepath.match(regex_suffix)[0]
}
/**
*
*/
function getDateString(){
function appendLeadingZeroes(n){
if(n <= 9){
return "0" + n;
}
return n
}
let current_datetime = new Date()
console.log(current_datetime.toString());
let formatted_date = current_datetime.getFullYear() + "-" + appendLeadingZeroes(current_datetime.getMonth() + 1) + "-" + appendLeadingZeroes(current_datetime.getDate()) + "T" + appendLeadingZeroes(current_datetime.getHours()) + ":" + appendLeadingZeroes(current_datetime.getMinutes()) + ":" + appendLeadingZeroes(current_datetime.getSeconds())
return formatted_date
}
/**
* Registers a custom action
*
* @param identifier the identifier of the action
* @param menuText the text shown in the menu
* @param buttonText the text shown in the button
* (no button will be viewed if empty)
* @param icon the icon file path or the name of a freedesktop theme icon
* you will find a list of icons here:
* https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
* @param useInNoteEditContextMenu if true use the action in the note edit
* context menu (default: false)
* @param hideButtonInToolbar if true the button will not be shown in the
* custom action toolbar (default: false)
* @param useInNoteListContextMenu if true use the action in the note list
* context menu (default: false)
*/
function init() {
script.registerCustomAction("fileExport", "Export selected files", "Export files", "archive-extract", true, false, true);
script.registerCustomAction("formatAttachments", "Format Attachments/Media links", "Expert filesFormat Attachments/Media links", "edit-guides", true, false, true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier === "fileExport") {
exportFiles()
}
if (identifier === "formatAttachments") {
formatAttachments()
}
}
/**
* Add/remove line breaks to align media links neatly
*/
function formatAttachments(){
const regex_media = /(\s*)(!?\[.+?\]\(.+?\))/gm; // additional '(' create a group to be used as $1
const note = script.currentNote();
var match;
if(script.noteTextEditSelectedText().length === 0){
script.noteTextEditSelectAll(); // format entire note if nothing is selected
}
var currentSelectedText = script.noteTextEditSelectedText();
script.noteTextEditWrite(currentSelectedText.replace(regex_media, "\n$2 ")) // " " -> newline
}
}