Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mdhelp: allow to override (extend) property docs - example - DVR config
  • Loading branch information
perexg committed Apr 6, 2016
1 parent e6bab99 commit 957b835
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 27 deletions.
7 changes: 7 additions & 0 deletions Makefile
Expand Up @@ -547,9 +547,11 @@ SRCS-yes += src/docs.c
I18N-C += src/docs_inc.c
I18N-DOCS = $(wildcard docs/markdown/*.md)
I18N-DOCS += $(wildcard docs/class/*.md)
I18N-DOCS += $(wildcard docs/property/*.md)
I18N-DOCS += $(wildcard docs/wizard/*.md)
MD-ROOT = $(patsubst docs/markdown/%.md,%,$(wildcard docs/markdown/*.md))
MD-CLASS = $(patsubst docs/class/%.md,%,$(wildcard docs/class/*.md))
MD-PROP = $(patsubst docs/property/%.md,%,$(wildcard docs/property/*.md))
MD-WIZARD = $(patsubst docs/wizard/%.md,%,$(wildcard docs/wizard/*.md))

#
Expand Down Expand Up @@ -681,6 +683,11 @@ $(BUILDDIR)/docs-timestamp: $(I18N-DOCS) support/doc/md_to_c.py
$(MD-TO-C) --in="docs/class/$${i}.md" \
--name="tvh_doc_$${i}_class" >> src/docs_inc.c || exit 1; \
done
@for i in $(MD-PROP); do \
echo "Markdown: docs/property/$${i}.md"; \
$(MD-TO-C) --in="docs/property/$${i}.md" \
--name="tvh_doc_$${i}_property" >> src/docs_inc.c || exit 1; \
done
@for i in $(MD-WIZARD); do \
echo "Markdown: docs/wizard/$${i}.md"; \
$(MD-TO-C) --in="docs/wizard/$${i}.md" \
Expand Down
32 changes: 32 additions & 0 deletions docs/property/postprocessor.md
@@ -0,0 +1,32 @@
: Command to run after finishing a recording. The command will be run in
background and is executed even if a recording is aborted or an error
occurred. Use the %e error formatting string to check for errors, the
error string is “OK” if recording finished successfully.

Supported format strings:


Format | Description | Example value
:-----:| ----------------------------------------- | -------------
`%f` | Full path to recording | /home/user/Videos/News.mkv
`%b` | Basename of recording | News.mkv
`%c` | Channel name | BBC world
`%O` | Owner of this recording | user
`%C` | Who created this recording | user
`%t` | Program title | News
`%s` | Program subtitle | Afternoon
`%p` | Program episode | S02.E07
`%d` | Program description | News and stories…
`%e` | Error message | Aborted by user
`%S` | Start time stamp of recording, UNIX epoch | 1224421200
`%E` | Stop time stamp of recording, UNIX epoch | 1224426600
`%r` | Number of errors during recording | 0
`%R` | Number of data errors during recording | 6

*Example usage*

To use special characters (e.g. spaces), either put the string in quotes or
escape the individual characters.

```/path/to/ffmpeg -i "%f" -vcodec libx264 -acodec copy "/path/with white space/%b"```

17 changes: 13 additions & 4 deletions src/dvr/dvr_config.c
Expand Up @@ -791,6 +791,13 @@ dvr_config_class_pathname_set(void *o, const void *v)
return 0;
}

static char *
dvr_config_prop_pathname_doc(const struct property *p, const char *lang)
{
extern const char *tvh_doc_postprocessor_property[];
return prop_md_doc(tvh_doc_postprocessor_property, lang);
}

extern const char *tvh_doc_dvrconfig_class[];

const idclass_t dvr_config_class = {
Expand Down Expand Up @@ -897,7 +904,7 @@ const idclass_t dvr_config_class = {
.off = offsetof(dvr_config_t, dvr_retention_days),
.def.u32 = DVR_RET_ONREMOVE,
.list = dvr_config_class_retention_list,
.opts = PO_EXPERT,
.opts = PO_EXPERT | PO_DOC_NLIST,
.group = 1,
},
{
Expand All @@ -908,6 +915,7 @@ const idclass_t dvr_config_class = {
.off = offsetof(dvr_config_t, dvr_removal_days),
.def.u32 = DVR_RET_FOREVER,
.list = dvr_config_class_removal_list,
.opts = PO_DOC_NLIST,
.group = 1,
},
{
Expand Down Expand Up @@ -958,7 +966,7 @@ const idclass_t dvr_config_class = {
"in the channel or DVR entry will be used."),
.off = offsetof(dvr_config_t, dvr_extra_time_pre),
.list = dvr_config_class_extra_list,
.opts = PO_ADVANCED,
.opts = PO_ADVANCED | PO_DOC_NLIST,
.group = 1,
},
{
Expand All @@ -969,7 +977,7 @@ const idclass_t dvr_config_class = {
"stop time."),
.off = offsetof(dvr_config_t, dvr_extra_time_post),
.list = dvr_config_class_extra_list,
.opts = PO_ADVANCED,
.opts = PO_ADVANCED | PO_DOC_NLIST,
.group = 1,
},
{
Expand All @@ -981,7 +989,7 @@ const idclass_t dvr_config_class = {
.off = offsetof(dvr_config_t, dvr_update_window),
.list = dvr_config_entry_class_update_window_list,
.def.u32 = 24*3600,
.opts = PO_EXPERT,
.opts = PO_EXPERT | PO_DOC_NLIST,
.group = 1,
},
{
Expand Down Expand Up @@ -1125,6 +1133,7 @@ const idclass_t dvr_config_class = {
.desc = N_("The string allows you to manually specify the "
"full path generation using predefined "
"modifiers. See Help for full details."),
.doc = dvr_config_prop_pathname_doc,
.set = dvr_config_class_pathname_set,
.off = offsetof(dvr_config_t, dvr_pathname),
.opts = PO_EXPERT,
Expand Down
5 changes: 3 additions & 2 deletions src/idnode.h
Expand Up @@ -231,8 +231,9 @@ void idnode_read0 (idnode_t *self, htsmsg_t *m, htsmsg_t *list, int optmas
int idnode_write0 (idnode_t *self, htsmsg_t *m, int optmask, int dosave);
void idnode_save_check (idnode_t *self, int weak);

#define idclass_serialize(idc, lang) idclass_serialize0(idc, NULL, 0, lang)
#define idnode_serialize(in, lang) idnode_serialize0(in, NULL, 0, lang)
#define idclass_serialize(idc, lang) idclass_serialize0(idc, NULL, 0, lang)
#define idclass_serializedoc(idc, lang) idclass_serialize0(idc, NULL, PO_DOC, lang)
#define idnode_serialize(in, lang) idnode_serialize0(in, NULL, 0, lang)
#define idnode_load(in, m) idnode_write0(in, m, PO_NOSAVE, 0)
#define idnode_save(in, m) idnode_read0(in, m, NULL, PO_NOSAVE | PO_USERAW, NULL)
#define idnode_update(in, m) idnode_write0(in, m, PO_RDONLY | PO_WRONCE, 1)
Expand Down
38 changes: 38 additions & 0 deletions src/prop.c
Expand Up @@ -422,6 +422,13 @@ prop_serialize_value

/* Metadata */
htsmsg_add_str(m, "caption", tvh_gettext_lang(lang, pl->name));
if ((optmask & PO_DOC) && pl->doc) {
char *s = pl->doc(pl, lang);
if (s) {
htsmsg_add_str(m, "doc", s);
free(s);
}
}
if (pl->desc)
htsmsg_add_str(m, "description", tvh_gettext_lang(lang, pl->desc));
if (pl->islist) {
Expand Down Expand Up @@ -498,6 +505,8 @@ prop_serialize_value
htsmsg_add_bool(m, "multiline", 1);
if (opts & PO_PERSIST)
htsmsg_add_bool(m, "persistent", 1);
if ((optmask & PO_DOC) && (opts & PO_DOC_NLIST))
htsmsg_add_bool(m, "doc_nlist", 1);

/* Enum list */
if (pl->list) {
Expand Down Expand Up @@ -567,6 +576,35 @@ prop_serialize
}
}

/**
*
*/
char *
prop_md_doc(const char **doc, const char *lang)
{
const char *s;
char *r = NULL;
size_t l = 0;

for (; *doc; doc++) {
if (*doc[0] == '\xff') {
s = tvh_gettext_lang(lang, *doc + 1);
} else {
s = *doc;
}
if (r == NULL) {
r = strdup(s);
l = strlen(s);
} else {
l += strlen(s) + 1;
r = realloc(r, l);
strcat(r, s);
}
}
return r;
}


/******************************************************************************
* Editor Configuration
*
Expand Down
8 changes: 8 additions & 0 deletions src/prop.h
Expand Up @@ -63,6 +63,8 @@ typedef enum {
#define PO_LORDER (1<<15) // Manage order in lists
#define PO_MULTILINE (1<<16) // Multiline string
#define PO_PERSIST (1<<17) // Persistent value (return back on save)
#define PO_DOC (1<<18) // Use doc callback instead description if exists
#define PO_DOC_NLIST (1<<19) // Do not show list in doc

/*
* min/max/step helpers
Expand Down Expand Up @@ -114,6 +116,9 @@ typedef struct property {
/* Extended options */
uint32_t (*get_opts) (void *ptr);

/* Documentation callback */
char *(*doc) ( const struct property *prop, const char *lang );

/* Notification callback */
void (*notify) (void *ptr, const char *lang);

Expand Down Expand Up @@ -144,6 +149,9 @@ static inline int64_t prop_intsplit_from_str(const char *s, int64_t intsplit)
return s64;
}

char *
prop_md_doc(const char **md, const char *lang);

#endif /* __TVH_PROP_H__ */

/******************************************************************************
Expand Down
37 changes: 22 additions & 15 deletions src/webui/doc_md.c
Expand Up @@ -140,7 +140,7 @@ http_markdown_class(http_connection_t *hc, const char *clazz)
return HTTP_STATUS_NOT_FOUND;
}
doc = ic->ic_doc;
m = idclass_serialize(ic, lang);
m = idclass_serializedoc(ic, lang);
pthread_mutex_unlock(&global_lock);
s = htsmsg_get_str(m, "caption");
if (s) {
Expand Down Expand Up @@ -186,22 +186,29 @@ http_markdown_class(http_connection_t *hc, const char *clazz)
md_text(hq, ": ", " ", s);
md_nl(hq, 1);
}
e = htsmsg_get_list(n, "enum");
if (e) {
HTSMSG_FOREACH(f2, e) {
x = htsmsg_field_get_map(f2);
if (x) {
s = htsmsg_get_str(x, "val");
} else {
s = htsmsg_field_get_string(f2);
}
if (s) {
md_nl(hq, 1);
htsbuf_append(hq, " * ", 4);
md_style(hq, "**", s);
s = htsmsg_get_str(n, "doc");
if (s) {
htsbuf_append_str(hq, s);
md_nl(hq, 1);
}
if (!htsmsg_get_bool_or_default(n, "doc_nlist", 0)) {
e = htsmsg_get_list(n, "enum");
if (e) {
HTSMSG_FOREACH(f2, e) {
x = htsmsg_field_get_map(f2);
if (x) {
s = htsmsg_get_str(x, "val");
} else {
s = htsmsg_field_get_string(f2);
}
if (s) {
md_nl(hq, 1);
htsbuf_append(hq, " * ", 4);
md_style(hq, "**", s);
}
}
md_nl(hq, 1);
}
md_nl(hq, 1);
}
}
htsmsg_destroy(m);
Expand Down
12 changes: 6 additions & 6 deletions src/webui/static/app/dvr.js
Expand Up @@ -320,7 +320,7 @@ tvheadend.dvr_upcoming = function(panel, index) {
selected: selected,
beforeedit: beforeedit,
help: function() {
new tvheadend.help(_('DVR - Upcoming/Current Recordings'), 'dvr_upcoming.html');
new tvheadend.mdhelp('class/dvrentry');
}
});

Expand Down Expand Up @@ -461,7 +461,7 @@ tvheadend.dvr_finished = function(panel, index) {
tbar: [downloadButton, rerecordButton, moveButton],
selected: selected,
help: function() {
new tvheadend.help(_('DVR - Finished Recordings'), 'dvr_finished.html');
new tvheadend.mdhelp('class/dvrentry');
}
});

Expand Down Expand Up @@ -602,7 +602,7 @@ tvheadend.dvr_failed = function(panel, index) {
tbar: [downloadButton, rerecordButton, moveButton],
selected: selected,
help: function() {
new tvheadend.help(_('DVR - Failed Recordings'), 'dvr_failed.html');
new tvheadend.mdhelp('class/dvrentry');
}
});

Expand All @@ -628,7 +628,7 @@ tvheadend.dvr_settings = function(panel, index) {
},
del: true,
help: function() {
new tvheadend.help(_('DVR'), 'config_dvr.html');
new tvheadend.mdhelp('class/dvrconfig');
}
});

Expand Down Expand Up @@ -696,7 +696,7 @@ tvheadend.autorec_editor = function(panel, index) {
direction: 'ASC'
},
help: function() {
new tvheadend.help(_('DVR Autorec'), 'dvr_autorec.html');
new tvheadend.mdhelp('class/dvrautorec');
}
});

Expand Down Expand Up @@ -749,7 +749,7 @@ tvheadend.timerec_editor = function(panel, index) {
direction: 'ASC'
},
help: function() {
new tvheadend.help(_('DVR Timers'), 'dvr_timerec.html');
new tvheadend.mdhelp('class/dvrtimerec');
}
});

Expand Down

0 comments on commit 957b835

Please sign in to comment.