]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Add Season number and Episode number to file name formatting strings.
authorDeltaMikeCharlie <127641886+DeltaMikeCharlie@users.noreply.github.com>
Fri, 27 Jun 2025 07:56:47 +0000 (17:56 +1000)
committerFlole <Flole998@users.noreply.github.com>
Fri, 18 Jul 2025 00:38:26 +0000 (02:38 +0200)
docs/property/autorec_directory.md [new file with mode: 0644]
docs/property/pathname.md
docs/property/postprocessor.md
docs/property/postremove.md
docs/property/preprocessor.md
src/dvr/dvr_autorec.c
src/dvr/dvr_rec.c

diff --git a/docs/property/autorec_directory.md b/docs/property/autorec_directory.md
new file mode 100644 (file)
index 0000000..98b8329
--- /dev/null
@@ -0,0 +1,3 @@
+**Note:** If the directory name starts with $$, then format
+string substitution from the [DVR profile](class/dvrconfig) is also
+performed here.
\ No newline at end of file
index 452b24eae2b04107d89f103f40c9baaac01c9522..bf6f5aec33c7af0bc2f787a175eebff5b09759ad 100644 (file)
@@ -11,6 +11,8 @@ Format    | Description                                      | Example
 `$u`      | Event subtitle name                              | Tennis
 `$m`      | Event summary text                               | Live Tennis Broadcast from Wimbledon
 `$e`      | Event episode name                               | S02-E06
+`$A`      | Event season number                              | 2
+`$B`      | Event episode number                             | 6
 `$c`      | Channel name                                     | SkySport
 `$g`      | Content type                                     | Movie : Science fiction
 `$Q`      | Scraper friendly (see below)                     | Gladiator (2000)
@@ -84,6 +86,17 @@ Examples for `$3Q` are:
 Typically the `$q` and `$Q` formats would be combined with other
 modifiers to generate a complete filename such as `$q$n.$x`.
 
+The `$B` and `$A` formats also have numeric modifiers to specify when
+zero padded values are required.
+
+For example, with S02-E06:
+- `$A` would insert `2` into the file name.
+- `$2A` would insert `02` into the file name.
+- `$B` would insert `6` into the file name.
+- `$3B` would insert `006` into the file name.
+
+With sufficiently accurate EPG data, the formatting string `$t/Season $A/$2B-$u$n.$x` would produce a recording named `/path/to/recordings/Bones/Season 2/06-The Girl in Suite 2103.ts`.
+
 Even with correct guide information, external scrapers can retrieve
 incorrect results. A famous example being the detective tv series
 "Castle" is often incorrectly retrieved as a much earlier tv show
index 869b69ca168eae9371b8c08ce90ebbe04d48b42b..f02ffb568c722de993c1097b1559b8bbe436ba21 100644 (file)
@@ -18,6 +18,8 @@ Format | Description                               | Example value
 `%u`   | Program subtitle                          |  Afternoon
 `%m`   | Program summary                           |  Afternoon fast news
 `%p`   | Program episode                           |  S02.E07
+`%A`   | Program season number                     |  2
+`%B`   | Program episode number                    |  7
 `%d`   | Program description                       |  News and stories…
 `%g`   | Program content type                      |  Current affairs
 `%e`   | Error message                             |  Aborted by user
index 210cf099757b13c3e8a61d5bab693a1408ed06fc..2c75eba57506ad8369904ec234e5acf0e0ea78cb 100644 (file)
@@ -16,6 +16,8 @@ Format | Description                               | Example value
 `%t`   | Program title                             |  News
 `%s`   | Program subtitle                          |  Afternoon
 `%p`   | Program episode                           |  S02.E07
+`%A`   | Program season number                     |  2
+`%B`   | Program episode number                    |  7
 `%d`   | Program description                       |  News and stories…
 `%e`   | Error message                             |  Aborted by user
 `%S`   | Start time stamp of recording, UNIX epoch |  1224421200
index 74730231ea9ba283c3bccfb942457df55b0275d6..75f98de33452442251d7df219679ff0a14d5d4be 100644 (file)
@@ -16,6 +16,8 @@ Format | Description                               | Example value
 `%u`   | Program subtitle                          |  Afternoon
 `%m`   | Program summary                           |  Afternoon fast news
 `%p`   | Program episode                           |  S02.E07
+`%A`   | Program season number                     |  2
+`%B`   | Program episode number                    |  7
 `%d`   | Program description                       |  News and stories…
 `%S`   | Start time stamp of recording, UNIX epoch |  1224421200
 `%E`   | Stop time stamp of recording, UNIX epoch  |  1224426600
index d7b2f05b5fddcc3a583e4cef772f452e248b78ad..9258e65efbc8ce0db881de07a845fa6b636f1924 100644 (file)
@@ -1075,6 +1075,7 @@ dvr_autorec_entry_class_owner_opts(void *o, uint32_t opts)
 
 CLASS_DOC(dvrautorec)
 PROP_DOC(duplicate_handling)
+PROP_DOC(autorec_directory)
 
 /* We provide several category drop-downs to make it easy for user
  * to select several. So abstract the properties away since they
@@ -1132,8 +1133,8 @@ const idclass_t dvr_autorec_entry_class = {
                      "subdirectory rules (except the base directory) "
                      "defined in the DVR configuration and puts all "
                      "recordings done by this entry into the "
-                     "subdirectory named here. Note that Format Strings "
-                     "cannot be used here. See Help for more info."),
+                     "subdirectory named here. See Help for more info."),
+      .doc      = prop_doc_autorec_directory,
       .off      = offsetof(dvr_autorec_entry_t, dae_directory),
       .opts     = PO_EXPERT,
     },
index f9f971be7cffccb089d99598558af48ebc8d5ec5..680e1c36bee7fdcf53c08f7820a793614bbb92c7 100644 (file)
@@ -405,6 +405,58 @@ dvr_sub_uuid(const char *id, const char *fmt, const void *aux, char *tmp, size_t
   return tmp;
 }
 
+static const char *
+dvr_sub_episode_numeral(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen)
+{
+// *id contains the current field format string
+// *fmt contains the whole format string
+
+  enum return_numeral_type { 
+    RETURN_SERIES, RETURN_EPISODE
+  };
+  
+  const dvr_entry_t *de = aux;
+  size_t id_len = 0;
+  int return_type = RETURN_SERIES;
+  signed char output_len = -1;
+  epg_episode_num_t ep_num;
+  int print_val = 0;
+
+  if (de->de_bcast == NULL)
+    return "";
+
+  id_len = strlen(id);
+  if (id[id_len-1] == 'B'){
+    return_type = RETURN_EPISODE;
+  }
+
+  if (id_len != 1){
+    output_len = atoi(id);
+  }
+
+  epg_broadcast_get_epnum(de->de_bcast, &ep_num);
+
+  print_val = ep_num.s_num;
+  if(return_type == RETURN_EPISODE){
+    print_val = ep_num.e_num;
+  }
+
+  if(print_val == 0){
+    snprintf(tmp, tmplen, "%s", _("Unknown"));
+  }
+  else
+  {
+    if(output_len < 1){
+      snprintf(tmp, tmplen, "%d", print_val);
+    } else {
+      snprintf(tmp, tmplen, "%0*d", output_len, print_val);
+    }
+  }
+
+  return tmp;
+
+}
+
 static const char *
 dvr_sub_episode(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen)
 {
@@ -804,6 +856,26 @@ static htsstr_substitute_t dvr_subs_entry[] = {
   { .id = ".e",  .getval = dvr_sub_episode },
   { .id = ",e",  .getval = dvr_sub_episode },
   { .id = ";e",  .getval = dvr_sub_episode },
+  { .id = "B",   .getval = dvr_sub_episode_numeral },
+  { .id = "1B",  .getval = dvr_sub_episode_numeral },
+  { .id = "2B",  .getval = dvr_sub_episode_numeral },
+  { .id = "3B",  .getval = dvr_sub_episode_numeral },
+  { .id = "4B",  .getval = dvr_sub_episode_numeral },
+  { .id = "5B",  .getval = dvr_sub_episode_numeral },
+  { .id = "6B",  .getval = dvr_sub_episode_numeral },
+  { .id = "7B",  .getval = dvr_sub_episode_numeral },
+  { .id = "8B",  .getval = dvr_sub_episode_numeral },
+  { .id = "9B",  .getval = dvr_sub_episode_numeral },
+  { .id = "A",   .getval = dvr_sub_episode_numeral },
+  { .id = "1A",  .getval = dvr_sub_episode_numeral },
+  { .id = "2A",  .getval = dvr_sub_episode_numeral },
+  { .id = "3A",  .getval = dvr_sub_episode_numeral },
+  { .id = "4A",  .getval = dvr_sub_episode_numeral },
+  { .id = "5A",  .getval = dvr_sub_episode_numeral },
+  { .id = "6A",  .getval = dvr_sub_episode_numeral },
+  { .id = "7A",  .getval = dvr_sub_episode_numeral },
+  { .id = "8A",  .getval = dvr_sub_episode_numeral },
+  { .id = "9A",  .getval = dvr_sub_episode_numeral },
   { .id = "c",   .getval = dvr_sub_channel },
   { .id = " c",  .getval = dvr_sub_channel },
   { .id = "-c",  .getval = dvr_sub_channel },
@@ -947,6 +1019,8 @@ static htsstr_substitute_t dvr_subs_postproc_entry[] = {
   { .id = "r",  .getval = dvr_sub_errors },
   { .id = "R",  .getval = dvr_sub_data_errors },
   { .id = "Z",  .getval = dvr_sub_comment },
+  { .id = "B",  .getval = dvr_sub_episode_numeral },
+  { .id = "A",  .getval = dvr_sub_episode_numeral },
   { .id = NULL, .getval = NULL }
 };