Compare commits

...

77 Commits
4.2.0 ... main

Author SHA1 Message Date
Scott McGrath 5b4c720e10
fix(playout): improve the way hashlib is called in libretime_playout/player (#3135)
### Description

Improves the way hashlib is called in libretime_playout/player so that
is isn't broken on systems with python < 3.9

The way it is currently called in
site-packages/libretime_playout/player/file.py, in the section where
scheduled files are copied to the cache dir for playout, specifies the
usedforsecurity=False flag as follows:
`hasher = hashlib.md5(usedforsecurity=False)`

hashlib.md5 did not support this flag until Python 3.9. Attempting to
specify the flag directly as an argument to hashlib.md5(), in an older
python environment (such as that in Ubuntu Focal 20.04), is unsafe, and
can cause hashlib.md5() to balk/throw an exception, which results in
file copy operations failing. This then precipitates into playout
problems, as scheduled media is missing from the cache folder.


This PR instead calls using hashlib.new(), and passes the argument to
that, as follows:
`hasher = hashlib.new('md5', usedforsecurity=False)`

This method of calling with the flag argument is safer, because the
constructor will take it or leave it gracefully, regardless of whether
the system has a version of hashlib that supports the `usedforsecurity`
flag. AFAICT, it improves (fixes) function on older systems without
negatively impacting others.

### Testing Notes

**What I did:**
Before applying this patch, we were experiencing occasional but fairly
regular periods of silence when the system was supposed to be playing a
song or track. This behavior was consistent with errors such as the
following being present in the playout log:
```
2025-01-15 14:01:28,331 | INFO     | libretime_playout.player.file:copy_file:47 - copying file 19834 to cache /var/lib/libretime/playout/scheduler/19834.mp3
2025-01-15 14:01:28,466 | ERROR    | libretime_playout.player.file:copy_file:77 - could not copy file 19834 to /var/lib/libretime/playout/scheduler/19834.mp3: 'usedforsecurity' is an invalid keyword argument for openssl_md5()
Traceback (most recent call last):
  File "/opt/libretime/lib/python3.8/site-packages/libretime_playout/player/file.py", line 70, in copy_file
    file_event.filesize = self.report_file_size_and_md5_to_api(
  File "/opt/libretime/lib/python3.8/site-packages/libretime_playout/player/file.py", line 89, in report_file_size_and_md5_to_api
    hasher = hashlib.md5(usedforsecurity=False)
TypeError: 'usedforsecurity' is an invalid keyword argument for openssl_md5()
```
_For more information about the characterization and results of this
problem, see issue #3134_

**Testing on running systems**
After the patch was applied, these errors were no longer seen. I first
tested this on a dev server, and then on a live server, with
approximately 100 distinct tracks of playout occurring over about 24
hours. There were no file copy failures, and no related playout
problems, which was a major and immediate improvement.

**Testing installer, fresh installs**
***Ubuntu 20.04***
I deployed a patch to the installer and installed it on a blank system
running Ubuntu 20.04 and tested it to make sure the fix was applied and
worked.

***Debian 11***
I deployed patch to the installer and installed it on a blank system
running Debian Bullseye (which runs python = 3.9) , and tested it there
to make sure it did not break anything or introduce a regression.


### **Links**

Closes: #3134
2025-01-17 23:11:02 +00:00
Kyle Robbertze a14f1bec0b
ci: only check last commit for API schema in PRs (#3133)
### Description

PRs are intended to be squashed to a single commit. Only checking the
last commit gives us the intended state of the repo and ensures that if
the author commits the schema fixes later, the CI passes as expected.
Currently, the CI will fail because the earlier commits still have an
out of date schema.
2025-01-10 16:56:39 +00:00
nosbig 203c927554
feat: add flac support to Web player (#3128)
### Description

Added support for previewing FLAC files in the web interface, provided
in #509 by marmotte32 on Github in the comments for this issue.

I have tested this against a script-installed copy of 4.2.0, and FLAC
preview is working, although auto-play isn't. I haven't tested to
confirm if this behavior matches MP3 and OGG uploads.

**This is a new feature**:

_Do the changes in this PR implement a new feature?_

**I have updated the documentation to reflect these changes**:

No changes needed; this bug is a missing file format in preview, and it
requires no updates to the documentation.

### Testing Notes

**What I did:**

I installed a LibreTime 4.2.0 system using the default installation
script against a fully-updated, brand new Debian 11 system. I logged
into the web interface, uploaded some FLAC files, and attempted to
preview them. They failed to preview.

I then replaced the preview_jplayer.js file with the contents in this PR
and then refreshed the page. I was able to preview the FLAC files and
hear the results in my local browser audio output.

**How you can replicate my testing:**

Perform the same steps above, or replace the same file in the
libretime_legacy_1 docker image to see the same results.

### **Links**

Closes: #509

---------

Co-authored-by: Kyle Robbertze <kyle@paddatrapper.com>
2025-01-10 15:46:18 +00:00
Kyle Robbertze 6f5275176e
chore: update docker compose commands (#3132)
### Description

Upstream has renamed docker-compose to docker compose for all commands

**This is a new feature**:

_Do the changes in this PR implement a new feature?_

**I have updated the documentation to reflect these changes**:

Yes
2025-01-09 16:09:28 +00:00
Scott McGrath 644d2b9ce5
fix(legacy): additional specifics added to CSVexport.js for RFC 4180 (#3131)
### Description

The existing implementation for exporting playout logs to a CSV file
incorporates a very simplified CSV format. Some aspects of the complete
[RFC](https://www.rfc-editor.org/rfc/rfc4180) are missing, such as
escaping of quotes, and quoting of fields that contain certain
characters. This is problematic for common office spreadsheet tools, and
practically, anything else. Many radio stations rely on this
functionality to work well for exporting playout data, for example, in
order to compile data for reporting requirements.

**This is a new feature**:

The changes in this PR add quoting of fields containing a comma, as well
as those containing a CR/LF. It also escapes quotes by doubling them.
I'm not sure it makes CSVexport.js completely RFC 4180 compliant, but it
is much closer than it was.

**I have updated the documentation to reflect these changes**:

I don't think there are any documentation changes necessary; this is
probably expected behavior for anyone trying to use the CSV exporter.

### Testing Notes

**What I did:**

To validate this, I did a clean install of Debian, cloned from the
official libretime repo, and applied the code as a patch to the
installer. I then proceeded with the install and then loaded a database
from a running system (so that I had some playout data to test with). I
then performed the playout history export and examined the resulting CSV
file and after seeing previously problematic fields properly quoted, was
convinced it looked the way I expected. I loaded the csv file into
Libreoffice Calc and did not see any errors.

**How you can replicate my testing:**

See "What I did" above, basically run the patch after cloning the
installer from the repo. You could also apply the changes to a running
system by applying the patch to the file:
/usr/share/libretime/legacy/public/js/libs/CSVexport.js
Be sure to clear your browser cache and do a hard reload of the web
interface, before re-testing.

### **Links**

Closes: #2477
2025-01-09 08:34:13 +00:00
Kyle Robbertze 267da9e438
chore: add pre-commit API check (#3120)
### Description

This is a way of ensuring the schema is up to date with every change.
This should be extended by fixing the PR api schema pipeline to squash
down all PR commits into a single change and checking the API schema for
that. Otherwise people will fix the schema after a failed pipeline and
the pipeline will continue to fail
2025-01-09 07:53:49 +00:00
Keoni Mahelona b1bdd6d9be
feat(api): added filters on genre & md5 for files api (#3127)
### Description
Added filters for genre and md5 to the files API, e.g.
`/api/v2/files?genre=soul`

**This is a new feature**: Yes

**I have updated the documentation to reflect these changes**: No
There should be a schema and docs that are generated automatically. I
don't know where that is.


### Testing Notes

**What I did:**
- Used docker to deploy locally
- Confirmed filters work at
http://localhost:8080/api/v2/files?genre=Soul

**How you can replicate my testing:**
- `make clean dev`
- Upload some files!
- Visit http://localhost:8080/api/v2/files
- You can use the filters
<img width="658" alt="Screenshot 2024-12-23 at 01 36 01"
src="https://github.com/user-attachments/assets/ba19f7f3-fb3e-495d-8937-d451c70d326c"
/>
<img width="652" alt="Screenshot 2024-12-23 at 01 35 56"
src="https://github.com/user-attachments/assets/c7191131-a963-463a-b52f-9d0952192555"
/>

_How can the reviewer validate this PR?_
- See above
- wrote tests to confirm filters work
2025-01-08 16:54:53 +00:00
Kyle Robbertze 92ca6b0341
ci: make libretime test user owner of test database (#3130)
Fix the legacy tests
2025-01-08 16:53:45 +00:00
Weblate (bot) 7f40743d83
chore(legacy): translations update from Hosted Weblate (#3129)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: marmotte <serge@e.email>
2025-01-08 10:48:31 +00:00
Scott McGrath 82d5af2dfb
fix(legacy): migrations from airtime 2.5.1 (#3123)
### Description

This fixes various problems in legacy migrations that were preventing a
successful database migration from Airtime 2.5.1. Previously, following
[the
procedure](https://libretime.org/docs/admin-manual/install/migrate-from-airtime/)
using the migrations provided in the Libretime 4.2.0 installer, without
the fixes in this PR, would either fail completely, or cause all of the
imported data to be completely deleted.


_migrations.py
If schema_version is not found in the table cc_prefs, it then checks for
system_version to have a value of '2.5.1' (in case this is an airtime
2.5.1 migration which will not have any schema_version in cc_pref). If
found, it prevents loading of the schema file, which is critical to
preserving the imported Airtime data.

0006_2_5_5
Removed a redundant addition of the image_path and description columns
to cc_show (done in earlier migration 003_2_5_2)

0015_2_5_17
Fixed a syntax error with adding the artwork column to cc_files

0023_3_0_0_alpha_9_1
Removed a redundant addition of the artwork column to cc_files (done in
earlier migration 0015_2_5_7)

### Documentation Changes

The [airtime migration
documentation](https://libretime.org/docs/admin-manual/install/migrate-from-airtime/)
already suggests a procedure to be followed, it just didn't work because
of problems within these migrations. The procedure as documented should
now work for those coming from Airtime 2.5.1.

### Testing Notes

**What I did:**

I attempted to migrate an actual airtime 2.5.1 database from a
production system containing a large amount of shows, tracks, and users.
I observed that the migration completed without errors, and that the
expected system state was achieved within Libretime. Specifically, the
calendar, library, authentication, and other aspects are populated with
the data that was present in the migrated Airtime database, and
Libretime is able to function using this data.

**How you can replicate my testing:**

Install Libretime 4.2.0. Restore a sample postrgresql database backup
from an Airtime 2.5.1 server. Apply the database migration. Restart the
services. Login and view the library, calender, etc.

### **Links**

Closes: #3121  
May also be related to, or even close (as a duplicate): #2563
2024-12-21 10:09:19 +00:00
libretime-bot cf172d5c7c chore(legacy): update locales 2024-12-09 02:37:27 +00:00
renovate[bot] f1c9ebf6f2
chore(deps): update dependency drf-spectacular to >=0.22.1,<0.29 (#3117)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[drf-spectacular](https://redirect.github.com/tfranzel/drf-spectacular)
| `>=0.22.1,<0.28` -> `>=0.22.1,<0.29` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/drf-spectacular/0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/drf-spectacular/0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/drf-spectacular/0.27.2/0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/drf-spectacular/0.27.2/0.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>tfranzel/drf-spectacular (drf-spectacular)</summary>

###
[`v0.28.0`](https://redirect.github.com/tfranzel/drf-spectacular/blob/HEAD/CHANGELOG.rst#0280-2024-11-30)

[Compare
Source](https://redirect.github.com/tfranzel/drf-spectacular/compare/0.27.2...0.28.0)

- Fix lazy_reverse bug in views (`#&#8203;1339
<https://github.com/tfranzel/drf-spectacular/issues/1339>`\_)
- Extend query params explosion of non-DRF serializer `#&#8203;1315
<https://github.com/tfranzel/drf-spectacular/issues/1315>`\_
- consider pk_field on PrimaryKeyRelatedField when set `#&#8203;1335
<https://github.com/tfranzel/drf-spectacular/issues/1335>`\_
- fix unused OAuth2 scopes override `#&#8203;1319
<https://github.com/tfranzel/drf-spectacular/issues/1319>`\_
-   bugfix @&#8203;extend_schema_field raw schema already in OAS3.1
- some minors (resolves `#&#8203;1147
<https://github.com/tfranzel/drf-spectacular/issues/1147>`\_)
- fix OAS3.1 validator omission `#&#8203;1302
<https://github.com/tfranzel/drf-spectacular/issues/1302>`\_
- guard against broken **dir** impl `#&#8203;1296
<https://github.com/tfranzel/drf-spectacular/issues/1296>`\_
-   Add Django 5.1 as classifier \[jelmert]
-   No extra items in the oneOf list \[Vladimir]
- parametrize component registry identity `#&#8203;1288
<https://github.com/tfranzel/drf-spectacular/issues/1288>`\_
- make operation_id action position configurable `#&#8203;1264
<https://github.com/tfranzel/drf-spectacular/issues/1264>`\_
-   Fix for incorrect `issubclass()` check. \[Mike Moore]
- Correct the documentation of how to import extension snippets \[Alan
Crosswell]
-   Update OpenAPI docs links \[Nils Van Zuijlen]
- mitigate false positive in Django Debug Toolbar `#&#8203;1159
<https://github.com/tfranzel/drf-spectacular/issues/1159>`\_
-   Additional testcase \[Marti Raudsepp]
- Fix ChoiceField schema type with empty `choices=[]` \[Marti Raudsepp]
-   handle examples with nested properties pagination \[François Rejeté]
- add choice field display method handling `#&#8203;1228
<https://github.com/tfranzel/drf-spectacular/issues/1228>`\_
- Add support for stateless user authentication in SimpleJWT
(`#&#8203;1221
<https://github.com/tfranzel/drf-spectacular/issues/1221>`\_) \[Willem
Meints]
-   fix: set pydantic json mode to serialization \[Eric Butler]
-   fix: extend_schema_field with dict param and oas 3.1 \[Eric Butler]

Breaking changes / important additions:

-   Y-stream release due to the amount of small but important changes.
- Pydantic users might see a slightly different schema due to the change
in serialization method.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xOS4wIiwidXBkYXRlZEluVmVyIjoiMzkuNDIuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicHl0aG9uIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-07 12:13:03 +00:00
dakriy 2985d8554a
feat(legacy): trused header sso auth (#3095)
### Description

Allows LibreTime to support Trusted Header SSO Authentication.

**This is a new feature**:

Yes

**I have updated the documentation to reflect these changes**:

Yes

### Testing Notes

**What I did:**

I spun up an Authelia/Traefik pair and configured them to protect
LibreTime according to Authelia's documentation, I then tested that you
could log in via the trusted headers, and tested that old methods of
authentication were not affected.

**How you can replicate my testing:**

Using the following `docker-compose.yml` file

```yml
services:
  postgres:
    image: postgres:15
    networks:
      - internal
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-libretime}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-libretime} # Change me !
    healthcheck:
      test: pg_isready -U libretime

  rabbitmq:
    image: rabbitmq:3.13-alpine
    networks:
      - internal
    environment:
      RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_DEFAULT_VHOST:-/libretime}
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-libretime}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-libretime} # Change me !
    healthcheck:
      test: nc -z 127.0.0.1 5672

  playout:
    image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_playout:/app
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  liquidsoap:
    image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    command: /usr/local/bin/libretime-liquidsoap
    init: true
    ulimits:
      nofile: 1024
    ports:
      - 8001:8001
      - 8002:8002
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_playout:/app
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  analyzer:
    image: ghcr.io/libretime/libretime-analyzer:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_storage:/srv/libretime
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  worker:
    image: ghcr.io/libretime/libretime-worker:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  api:
    image: ghcr.io/libretime/libretime-api:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - postgres
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_storage:/srv/libretime

  legacy:
    image: ghcr.io/libretime/libretime-legacy:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - postgres
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_assets:/var/www/html
      - libretime_storage:/srv/libretime

  nginx:
    image: nginx
    networks:
      - internal
      - net
    ports:
      - 8080:8080
    depends_on:
      - legacy
    volumes:
      - libretime_assets:/var/www/html:ro
      - libretime_storage:/srv/libretime:ro
      - ${NGINX_CONFIG_FILEPATH:-./nginx.conf}:/etc/nginx/conf.d/default.conf:ro
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=libretime_net'
      - 'traefik.http.routers.libretime.rule=Host(`libretime.example.com`)'
      - 'traefik.http.routers.libretime.entrypoints=https'
      - 'traefik.http.routers.libretime.tls=true'
      - 'traefik.http.routers.libretime.tls.options=default'
      - 'traefik.http.routers.libretime.middlewares=authelia@docker'
      - 'traefik.http.services.libretime.loadbalancer.server.port=8080'

  icecast:
    image: ghcr.io/libretime/icecast:2.4.4
    networks:
      - internal
    ports:
      - 8000:8000
    environment:
      ICECAST_SOURCE_PASSWORD: ${ICECAST_SOURCE_PASSWORD:-hackme} # Change me !
      ICECAST_ADMIN_PASSWORD: ${ICECAST_ADMIN_PASSWORD:-hackme} # Change me !
      ICECAST_RELAY_PASSWORD: ${ICECAST_RELAY_PASSWORD:-hackme} # Change me !

  traefik:
    image: traefik:v2.11.12
    container_name: traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - net
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
      - 'traefik.http.routers.api.entrypoints=https'
      - 'traefik.http.routers.api.service=api@internal'
      - 'traefik.http.routers.api.tls=true'
      - 'traefik.http.routers.api.tls.options=default'
      - 'traefik.http.routers.api.middlewares=authelia@docker'
    ports:
      - '80:80'
      - '443:443'
    command:
      - '--api'
      - '--providers.docker=true'
      - '--providers.docker.exposedByDefault=false'
      - '--entrypoints.http=true'
      - '--entrypoints.http.address=:80'
      - '--entrypoints.http.http.redirections.entrypoint.to=https'
      - '--entrypoints.http.http.redirections.entrypoint.scheme=https'
      - '--entrypoints.https=true'
      - '--entrypoints.https.address=:443'
      - '--log=true'
      - '--log.level=DEBUG'

  authelia:
    image: authelia/authelia
    container_name: authelia
    networks:
      - net
    volumes:
      - ./authelia:/config
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.authelia.rule=Host(`auth.example.com`)'
      - 'traefik.http.routers.authelia.entrypoints=https'
      - 'traefik.http.routers.authelia.tls=true'
      - 'traefik.http.routers.authelia.tls.options=default'
      - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/authz/forward-auth'  # yamllint disable-line rule:line-length
      - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
      - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'  # yamllint disable-line rule:line-length
      - 'traefik.http.services.authelia.loadbalancer.server.port=9091'
    restart: unless-stopped
    environment:
      - TZ=America/Los_Angeles

volumes:
  postgres_data: {}
  libretime_storage: {}
  libretime_assets: {}
  libretime_playout: {}

networks:
  internal:
  net:
```

The following libretime dev config modification:
```yml
general:
  public_url: https://libretime.example.com
  auth: LibreTime_Auth_Adaptor_Header

header_auth:
  group_map:
    host: lt-host
    program_manager: lt-pm
    admin: lt-admin
    superadmin: lt-superadmin
```

And the following authelia config file:

```yml
---
###############################################################
#                   Authelia configuration                    #
###############################################################

server:
  address: 'tcp://:9091'
  buffers:
    read: 16384
    write: 16384

log:
  level: 'debug'

totp:
  issuer: 'authelia.com'

identity_validation:
  reset_password:
    jwt_secret: 'a_very_important_secret'

authentication_backend:
  file:
    path: '/config/users_database.yml'

access_control:
  default_policy: 'deny'
  rules:
    - domain: 'traefik.example.com'
      policy: 'one_factor'
    - domain: 'libretime.example.com'
      policy: 'one_factor'

session:
  secret: 'insecure_session_secret'

  cookies:
    - name: 'authelia_session'
      domain: 'example.com'  # Should match whatever your root protected domain is
      authelia_url: 'https://auth.example.com'
      expiration: '1 hour'  # 1 hour
      inactivity: '5 minutes'  # 5 minutes

regulation:
  max_retries: 3
  find_time: '2 minutes'
  ban_time: '5 minutes'

storage:
  encryption_key: 'you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this'
  local:
    path: '/config/db.sqlite3'

notifier:
  filesystem:
    filename: '/config/notification.txt'
...
```

And the following authelia users database:

```yml
---
###############################################################
#                         Users Database                      #
###############################################################

# This file can be used if you do not have an LDAP set up.

# List of users
users:
  test:
    disabled: false
    displayname: "First Last"
    password: "$argon2id$v=19$m=16,t=2,p=1$SWVVVzcySlRLUEFkWWh2eA$qPs1ZmzmDXR/9WckDzIN9Q"
    email: test@example.com
    groups:
      - admins
      - dev
      - lt-admin
...
```

add the following entries to your `hosts` file:

```
127.0.0.1 traefik.example.com
127.0.0.1 auth.example.com
127.0.0.1 libretime.example.com
```

Then visit `libretime.example.com` in your browser, and login as the
user `test` with password of `password`. You should then be taken to the
LibreTime homepage, and when you click on login, you should be
automatically logged in.

### **Links**

https://www.authelia.com/integration/trusted-header-sso/introduction/
https://doc.traefik.io/traefik/middlewares/http/forwardauth/

---------

Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-12-07 10:21:57 +00:00
Weblate (bot) f709c5026d
chore(legacy): translations update from Hosted Weblate (#3116)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: gfbdrgng <hnaofegnp@hldrive.com>
2024-12-07 10:12:20 +00:00
Kyle Robbertze 38a0bf98b2 fix: regenerate API schema 2024-12-07 10:06:24 +00:00
renovate[bot] 3be4bd7da1
chore(deps): update pre-commit hook adamchainz/django-upgrade to v1.22.2 (#3119)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[adamchainz/django-upgrade](https://redirect.github.com/adamchainz/django-upgrade)
| repository | patch | `1.22.1` -> `1.22.2` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://redirect.github.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>adamchainz/django-upgrade (adamchainz/django-upgrade)</summary>

###
[`v1.22.2`](https://redirect.github.com/adamchainz/django-upgrade/blob/HEAD/CHANGELOG.rst#1222-2024-12-02)

[Compare
Source](https://redirect.github.com/adamchainz/django-upgrade/compare/1.22.1...1.22.2)

- Make these fixers work when `django.contrib.gis.db.models` is used to
import objects from `django.db.models`:

    -   `check_constraint_condition`
    -   `index_together`

`Issue #&#8203;513
<https://github.com/adamchainz/django-upgrade/issues/513>`\__.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS40Mi40IiwidXBkYXRlZEluVmVyIjoiMzkuNDIuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 10:22:41 +00:00
renovate[bot] c0bb7df0ed
chore(deps): lock file maintenance (legacy/composer.json) (#3118)
This PR contains the following updates:

| Update | Change |
|---|---|
| lockFileMaintenance | All locks refreshed |

🔧 This Pull Request updates lock files to use the latest dependency
versions.

---

### Configuration

📅 **Schedule**: Branch creation - "after 4am and before 5am on monday"
(UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS40Mi40IiwidXBkYXRlZEluVmVyIjoiMzkuNDIuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicGhwIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-03 06:39:40 +00:00
renovate[bot] d09bf04379
chore(deps): lock file maintenance (legacy/composer.json) (#3115)
This PR contains the following updates:

| Update | Change |
|---|---|
| lockFileMaintenance | All locks refreshed |

🔧 This Pull Request updates lock files to use the latest dependency
versions.

---

### Configuration

📅 **Schedule**: Branch creation - "after 4am and before 5am on monday"
(UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xOS4wIiwidXBkYXRlZEluVmVyIjoiMzkuMTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicGhwIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-26 06:13:26 +00:00
dakriy 02a779b413
feat(analyzer): parse comment fields from mp3 files (#3082)
### Description

Upload comments from mp3 files into libretime `comments` and
`description` fields.

**This is a new feature**:

Yes

**I have updated the documentation to reflect these changes**:

No none required

### Testing Notes

**What I did:**

I uploaded tracks that contained comments into LibreTime and checked the
database to ensure that the `comments` and `description` fields were
correctly populated. I then went to the UI and confirmed that the
description field had the MP3 comment in it inside of the metadata
editor. I then uploaded some files that did not have comments to make
sure I did not break any existing functionality.

**How you can replicate my testing:**

Follow the steps in what I did

### **Links**

Fixes #526

---------

Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-11-22 18:28:06 +00:00
Kyle Robbertze ce257a1f35 fix: regenerate API schema 2024-11-22 18:21:03 +00:00
Weblate (bot) 1939b0aec0
chore(legacy): translations update from Hosted Weblate (#3112)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-11-18 20:35:19 +00:00
Thomas Göttgens 2ac7e8a506
feat(api): enable writes to schedule table (#3109)
this fixes #3088

---------

Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-11-18 16:10:54 +00:00
renovate[bot] 824f6d2f1b
chore(deps): update codecov/codecov-action action to v5 (#3111)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[codecov/codecov-action](https://redirect.github.com/codecov/codecov-action)
| action | major | `v4` -> `v5` |

---

### Release Notes

<details>
<summary>codecov/codecov-action (codecov/codecov-action)</summary>

###
[`v5`](https://redirect.github.com/codecov/codecov-action/compare/v4...v5)

[Compare
Source](https://redirect.github.com/codecov/codecov-action/compare/v4...v5)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xMS41IiwidXBkYXRlZEluVmVyIjoiMzkuMTEuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiY2kiLCJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-16 00:29:08 +00:00
Weblate (bot) 013d68e880
chore(legacy): translations update from Hosted Weblate (#3110)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-11-14 00:00:22 +00:00
renovate[bot] 83b56f9cd0
chore(deps): update lycheeverse/lychee-action action to v2.1.0 (#3108)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[lycheeverse/lychee-action](https://redirect.github.com/lycheeverse/lychee-action)
| action | minor | `v2.0.2` -> `v2.1.0` |

---

### Release Notes

<details>
<summary>lycheeverse/lychee-action (lycheeverse/lychee-action)</summary>

###
[`v2.1.0`](https://redirect.github.com/lycheeverse/lychee-action/releases/tag/v2.1.0):
Version 2.1.0

[Compare
Source](https://redirect.github.com/lycheeverse/lychee-action/compare/v2.0.2...v2.1.0)

#### What's Changed

- Add missing argument `failIfEmpty` by
[@&#8203;LitoMore](https://redirect.github.com/LitoMore) in
[https://github.com/lycheeverse/lychee-action/pull/261](https://redirect.github.com/lycheeverse/lychee-action/pull/261)
- Fix bugs about the exit code by
[@&#8203;YDX-2147483647](https://redirect.github.com/YDX-2147483647) in
[https://github.com/lycheeverse/lychee-action/pull/262](https://redirect.github.com/lycheeverse/lychee-action/pull/262)
- Bump lychee version to 0.17.0 by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/263](https://redirect.github.com/lycheeverse/lychee-action/pull/263)

#### New Contributors

- [@&#8203;LitoMore](https://redirect.github.com/LitoMore) made their
first contribution in
[https://github.com/lycheeverse/lychee-action/pull/261](https://redirect.github.com/lycheeverse/lychee-action/pull/261)
- [@&#8203;YDX-2147483647](https://redirect.github.com/YDX-2147483647)
made their first contribution in
[https://github.com/lycheeverse/lychee-action/pull/262](https://redirect.github.com/lycheeverse/lychee-action/pull/262)

**Full Changelog**:
https://github.com/lycheeverse/lychee-action/compare/v2...v2.1.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS43LjEiLCJ1cGRhdGVkSW5WZXIiOiIzOS43LjEiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImNpIiwiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 18:08:43 +00:00
renovate[bot] c4e10ed861 chore(deps): lock file maintenance (legacy/composer.json) 2024-10-29 09:42:02 +00:00
libretime-bot 8d80e70580 chore(legacy): update locales 2024-10-28 02:21:53 +00:00
Weblate (bot) 26db439d34
chore(legacy): translations update from Hosted Weblate (#3105)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
2024-10-26 17:03:52 +01:00
renovate[bot] 380c6d0944 chore(deps): update pre-commit hook asottile/pyupgrade to v3.19.0 2024-10-23 11:21:05 +00:00
Thomas Göttgens 7992a9be2d
fix: intro/outro playlist unset was impossible (#3101)
this reinstates the boolean fields in the database from the original PR
to work around a foreign key contraint. THE UI remains unchanged
2024-10-21 18:34:39 +01:00
libretime-bot 2870857abc chore(legacy): update locales 2024-10-21 02:20:09 +00:00
Thomas Göttgens 0b221f4fff
fix(legacy): support Postgresql 12 syntax (#3103)
fixes #3102
2024-10-19 23:20:30 +01:00
renovate[bot] 188cd5d671
chore(deps): update dependency uvicorn to >=0.17.6,<0.33.0 (#3096)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [uvicorn](https://redirect.github.com/encode/uvicorn)
([changelog](https://redirect.github.com/encode/uvicorn/blob/master/CHANGELOG.md))
| `>=0.17.6,<0.32.0` -> `>=0.17.6,<0.33.0` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/uvicorn/0.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/uvicorn/0.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/uvicorn/0.31.1/0.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/uvicorn/0.31.1/0.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>encode/uvicorn (uvicorn)</summary>

###
[`v0.32.0`](https://redirect.github.com/encode/uvicorn/blob/HEAD/CHANGELOG.md#0320-2024-10-15)

[Compare
Source](https://redirect.github.com/encode/uvicorn/compare/0.31.1...0.32.0)

##### Added

- Officially support Python 3.13
([#&#8203;2482](https://redirect.github.com/encode/uvicorn/issues/2482))
- Warn when `max_request_limit` is exceeded
([#&#8203;2430](https://redirect.github.com/encode/uvicorn/issues/2430))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xMjAuMSIsInVwZGF0ZWRJblZlciI6IjM4LjEyMC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJweXRob24iXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-17 17:49:25 +01:00
Weblate (bot) 74da2ef0b4
chore(legacy): translations update from Hosted Weblate (#3099)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: Maurizio Castelvetro <castelvetro@gmail.com>
2024-10-17 17:49:06 +01:00
renovate[bot] 08b85a44bc chore(deps): lock file maintenance (legacy/composer.json) 2024-10-17 08:23:20 +00:00
renovate[bot] 2f0422b1ae chore(deps): update lycheeverse/lychee-action action to v2.0.2 2024-10-16 00:51:33 +00:00
renovate[bot] 9ce88538d3 chore(deps): update pre-commit hook asottile/pyupgrade to v3.18.0 2024-10-15 22:03:30 +00:00
Thomas Göttgens 299be3c142
feat: use custom intro/outro playlists per show (#2941)
### Description

Having a global intro and outro playlist in settings is not very
flexible for special programming. This adds an override intro/outro
playlist per show. If it is not set, the global one is used. also it's
ignored if there's no autloading at all.

**I have updated the documentation to reflect these changes**:

Yes

### Testing Notes

**What I did:**
Schedule 2 shows, one without defining custom lists, one with defining
custom lists. one hour before the show starts it should be populated
correctly. If you define a global list it shojuld be replaced with the
per-show list.

---------

Co-authored-by: Thomas Göttgens <tgoettgens@mail.com>
2024-10-14 21:07:41 +01:00
dakriy 5b5c68c628
feat(legacy): implement subset sum solution to show scheduling (#3019)
### Description

When running a radio station it is generally a good idea to reduce dead
air time. The current algorithm for adding tracks to a block/show can
leave a lot of dead air time at the end as it doesn't use a very good
algorithm. Adding tracks to a show until it is full while making it as
full as possible is a well known problem in computer science. It is the
[Subset Sum Problem](https://en.wikipedia.org/wiki/Subset_sum_problem).
This PR implements a Randomized Greedy with Local Improvement (RGLI)
approximation solution for the Subset Sum Problem. The new algorithm is
only used when sort type is random and overflow is not enabled and there
is no limit on the number of tracks that can be used.

**This is a new feature**:

Improvement on an existing feature. 

**I have not updated the documentation to reflect these changes**:

I did not update the documentation because the current scheduling
algorithm is not currently documented and its existing features have not
changed.

### Testing Notes

**What I did:**

I first attempted a fully polynomial time approximation scheme solution,
however it is really bad at finding good solutions for high density
values and can kinda slow the more tracks/time you have. So I instead
implemented an RGLI which is O(nlogn) and has been giving much better
results.

I implemented the solution in a separate project and tested it and timed
the values with a normal distribution of 500 songs with a mean of 3
minutes and a standard deviation of 1 minute. With a show size of 1 hour
the algorithm took around 10-15 ms to run. When adjusting the block size
and track size the algorithm still was pretty quick to run. Am going to
be testing on an instance with lots of tracks later, will update PR when
I have done that.

**How you can replicate my testing:**

_How can the reviewer validate this PR?_

### **Links**

Closes #3018
2024-10-13 15:31:08 +02:00
dakriy 16deaf08c6
feat(legacy): show filename and size on edit page and add filename datatable column (#3083)
### Description

Add File Name and Size to the metadata editor screen, and added a File
Name column to the tracks data table.

**This is a new feature**:

Yes

**I have updated the documentation to reflect these changes**:

No, just some simple UI additions so no documentation needed.

### Testing Notes

**What I did:**

I uploaded some tracks, clicked on edit, and saw that the filename and
size showed up at the top. I also went out to the tracks view and added
the File Name column and saw that the filename displayed properly.

**How you can replicate my testing:**

Do what I did

### **Links**

Fixes #3053
2024-10-13 08:45:54 +01:00
renovate[bot] 6d474c2733 chore(deps): update pre-commit hook adamchainz/django-upgrade to v1.22.1 2024-10-12 15:04:49 +00:00
renovate[bot] 2202618150
chore(deps): update lycheeverse/lychee-action action to v2 (#3091)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[lycheeverse/lychee-action](https://redirect.github.com/lycheeverse/lychee-action)
| action | major | `v1.10.0` -> `v2.0.0` |

---

### Release Notes

<details>
<summary>lycheeverse/lychee-action (lycheeverse/lychee-action)</summary>

###
[`v2.0.0`](https://redirect.github.com/lycheeverse/lychee-action/releases/tag/v2.0.0):
Version 2.0.0

[Compare
Source](https://redirect.github.com/lycheeverse/lychee-action/compare/v1.10.0...v2.0.0)

#### Breaking Changes

**Note:** This release improves the action's robustness by changing
default behaviors. Changes are only required if you want to opt out of
the new failure conditions. Most users won't need to modify their
existing configurations.

##### Fail pipeline on error by default

We've changed the default behavior: pipelines will now fail on broken
links automatically. This addresses user feedback that not failing on
broken links was unexpected (see [issue
#&#8203;71](https://redirect.github.com/lycheeverse/lychee-action/issues/71)).

**What you need to do:**

-   Update to version 2 of this action to apply this change.
- Users of the `lychee-action@master` branch don't need to make any
changes, as `fail: true` has been the default there for a while.
- If you prefer the old behavior, explicitly set `fail` to `false` when
updating:

```yaml
- name: Link Checker
  id: lychee
  uses: lycheeverse/lychee-action@v2
  with:
    fail: false  # Don't fail action on broken links
```

##### Fail pipeline if no links were found

Similar to the above change, we now fail the pipeline if no links are
found during a run. This helps warn users about potential configuration
issues.

**What you need to do:**

- If you expect links to be found in your pipeline run, you don't need
to do anything.
- If you expect no links in your pipeline run, you can opt out like
this:

```yaml
- name: Link Checker
  id: lychee
  uses: lycheeverse/lychee-action@v2
  with:
    failIfEmpty: false  # Don't fail action if no links were found
```

For a more detailed description of the technical aspects behind these
changes, please see the full changelog below.

#### What's Changed

- feat: change to use the full version tag with v-\* prefix by
[@&#8203;kemingy](https://redirect.github.com/kemingy) in
[https://github.com/lycheeverse/lychee-action/pull/204](https://redirect.github.com/lycheeverse/lychee-action/pull/204)
- Add `failIfEmpty` argument (fixes
[#&#8203;84](https://redirect.github.com/lycheeverse/lychee-action/issues/84))
by [@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/86](https://redirect.github.com/lycheeverse/lychee-action/pull/86)
- Fail pipeline on error by default (fixes
[#&#8203;71](https://redirect.github.com/lycheeverse/lychee-action/issues/71))
by [@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/85](https://redirect.github.com/lycheeverse/lychee-action/pull/85)
- Exit in case output is set in args and action input by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/227](https://redirect.github.com/lycheeverse/lychee-action/pull/227)
- v1 will automatically use latest version by
[@&#8203;jacobdalamb](https://redirect.github.com/jacobdalamb) in
[https://github.com/lycheeverse/lychee-action/pull/228](https://redirect.github.com/lycheeverse/lychee-action/pull/228)
- Remove unneeded text by
[@&#8203;jacobdalamb](https://redirect.github.com/jacobdalamb) in
[https://github.com/lycheeverse/lychee-action/pull/229](https://redirect.github.com/lycheeverse/lychee-action/pull/229)
- Clarify README.md defaults by
[@&#8203;paddyroddy](https://redirect.github.com/paddyroddy) in
[https://github.com/lycheeverse/lychee-action/pull/230](https://redirect.github.com/lycheeverse/lychee-action/pull/230)
- Adjust for new asset naming scheme by
[@&#8203;dscho](https://redirect.github.com/dscho) in
[https://github.com/lycheeverse/lychee-action/pull/234](https://redirect.github.com/lycheeverse/lychee-action/pull/234)
- Test various lychee versions by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/235](https://redirect.github.com/lycheeverse/lychee-action/pull/235)
- Better cleanup of old lychee assets by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/237](https://redirect.github.com/lycheeverse/lychee-action/pull/237)
- Bump peter-evans/create-issue-from-file from v4 to v5 by
[@&#8203;AndreiCherniaev](https://redirect.github.com/AndreiCherniaev)
in
[https://github.com/lycheeverse/lychee-action/pull/241](https://redirect.github.com/lycheeverse/lychee-action/pull/241)
- Remove dots from table by
[@&#8203;AndreiCherniaev](https://redirect.github.com/AndreiCherniaev)
in
[https://github.com/lycheeverse/lychee-action/pull/242](https://redirect.github.com/lycheeverse/lychee-action/pull/242)
- README: update actions/cache to v4 by
[@&#8203;sebastiaanspeck](https://redirect.github.com/sebastiaanspeck)
in
[https://github.com/lycheeverse/lychee-action/pull/243](https://redirect.github.com/lycheeverse/lychee-action/pull/243)
- Set exit_code correctly as output by
[@&#8203;sebastiaanspeck](https://redirect.github.com/sebastiaanspeck)
in
[https://github.com/lycheeverse/lychee-action/pull/245](https://redirect.github.com/lycheeverse/lychee-action/pull/245)
- action: fix failing CI by
[@&#8203;sebastiaanspeck](https://redirect.github.com/sebastiaanspeck)
in
[https://github.com/lycheeverse/lychee-action/pull/246](https://redirect.github.com/lycheeverse/lychee-action/pull/246)
- Split up steps in action by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/248](https://redirect.github.com/lycheeverse/lychee-action/pull/248)
- Bump version to 0.16.x, respect new tag names by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/249](https://redirect.github.com/lycheeverse/lychee-action/pull/249)
- Test latest lychee version tag by
[@&#8203;mre](https://redirect.github.com/mre) in
[https://github.com/lycheeverse/lychee-action/pull/236](https://redirect.github.com/lycheeverse/lychee-action/pull/236)

#### New Contributors

- [@&#8203;kemingy](https://redirect.github.com/kemingy) made their
first contribution in
[https://github.com/lycheeverse/lychee-action/pull/204](https://redirect.github.com/lycheeverse/lychee-action/pull/204)
- [@&#8203;paddyroddy](https://redirect.github.com/paddyroddy) made
their first contribution in
[https://github.com/lycheeverse/lychee-action/pull/230](https://redirect.github.com/lycheeverse/lychee-action/pull/230)
- [@&#8203;dscho](https://redirect.github.com/dscho) made their first
contribution in
[https://github.com/lycheeverse/lychee-action/pull/234](https://redirect.github.com/lycheeverse/lychee-action/pull/234)
- [@&#8203;AndreiCherniaev](https://redirect.github.com/AndreiCherniaev)
made their first contribution in
[https://github.com/lycheeverse/lychee-action/pull/241](https://redirect.github.com/lycheeverse/lychee-action/pull/241)
- [@&#8203;sebastiaanspeck](https://redirect.github.com/sebastiaanspeck)
made their first contribution in
[https://github.com/lycheeverse/lychee-action/pull/243](https://redirect.github.com/lycheeverse/lychee-action/pull/243)

**Full Changelog**:
https://github.com/lycheeverse/lychee-action/compare/v1...v1.11.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xMTQuMCIsInVwZGF0ZWRJblZlciI6IjM4LjExNC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJjaSIsImRlcGVuZGVuY2llcyJdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-10 10:17:10 +01:00
renovate[bot] ba69de0a2b chore(deps): update pre-commit hook psf/black-pre-commit-mirror to v24.10.0 2024-10-09 04:05:54 +00:00
dakriy 32cad0faa4
fix(analyzer): make ffmpeg filters less aggressive (#3086)
### Description

FFMPEG filters for silence detection are too aggressive.

**This is a new feature**:

No

**I have updated the documentation to reflect these changes**:

No

### Testing Notes

**What I did:**

Ran tests and made sure they passed

**How you can replicate my testing:**

Upload files that start out quiet or end quiet and see that the
cue-in/cue-out points don't cut off the track. Or just run tests as
there are files that do that

### **Links**

Closes: #2629
2024-10-07 20:55:18 +01:00
renovate[bot] 2643813fb7 chore(deps): update pre-commit hook pre-commit/pre-commit-hooks to v5 2024-10-07 03:56:39 +00:00
renovate[bot] a37050df9e
chore(deps): update dependency uvicorn to >=0.17.6,<0.32.0 (#3081)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [uvicorn](https://redirect.github.com/encode/uvicorn)
([changelog](https://redirect.github.com/encode/uvicorn/blob/master/CHANGELOG.md))
| `>=0.17.6,<0.31.0` -> `>=0.17.6,<0.32.0` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/uvicorn/0.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/uvicorn/0.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/uvicorn/0.30.6/0.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/uvicorn/0.30.6/0.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>encode/uvicorn (uvicorn)</summary>

###
[`v0.31.0`](https://redirect.github.com/encode/uvicorn/blob/HEAD/CHANGELOG.md#0310-2024-09-27)

[Compare
Source](https://redirect.github.com/encode/uvicorn/compare/0.30.6...0.31.0)

##### Added

Improve `ProxyHeadersMiddleware`
([#&#8203;2468](https://redirect.github.com/encode/uvicorn/issues/2468))
and
([#&#8203;2231](https://redirect.github.com/encode/uvicorn/issues/2231)):

- Fix the host for requests from clients running on the proxy server
itself.
- Fallback to host that was already set for empty x-forwarded-for
headers.
- Also allow to specify IP Networks as trusted hosts. This greatly
simplifies deployments
on docker swarm/kubernetes, where the reverse proxy might have a dynamic
IP.
    -   This includes support for IPv6 Address/Networks.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC45Ny4wIiwidXBkYXRlZEluVmVyIjoiMzguOTcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicHl0aG9uIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 16:32:04 +01:00
Kyle Robbertze bac903f4e5
chore: update django-stubs version (#3085)
Upstream has fixed the issue.

Closes: #3064
2024-09-30 16:15:28 +01:00
Kyle Robbertze 81e8fa90ed
chore: fix linting ignore comments (#3084)
### Description

There is now a too-many-positional-arguments check
2024-09-30 16:08:23 +01:00
renovate[bot] 004b784d09 chore(deps): lock file maintenance (legacy/composer.json) 2024-09-17 09:26:00 +00:00
Weblate (bot) 1ae9a7b368
chore(legacy): translations update from Hosted Weblate (#3077)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
2024-09-11 21:37:19 +01:00
Weblate (bot) 905008d72c
chore(legacy): translations update from Hosted Weblate (#3076)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-09-10 21:40:35 +01:00
libretime-bot 3b768644b2 chore(legacy): update locales 2024-09-09 02:14:15 +00:00
renovate[bot] 43f286c53d
chore(deps): update dependency friendsofphp/php-cs-fixer to <3.64.1 (#3058) 2024-09-07 21:14:32 +02:00
Jonas L. a3865aa6ee
fix: add missing file for nb_NO locale (#3075)
### Description

Related to #3073
2024-09-07 21:13:52 +02:00
renovate[bot] 4d737319d8 chore(deps): update pre-commit hook adamchainz/django-upgrade to v1.21.0 2024-09-07 18:41:07 +00:00
Jonas L. e614fbcf6c
feat: add Norwegian Bokmål locale (#3073)
### Description

Locale was requested on Weblate.
2024-09-06 14:43:40 +01:00
renovate[bot] d929871060 chore(deps): lock file maintenance (legacy/composer.json) 2024-09-03 10:37:34 +00:00
cdr78621 e344154d42
docs: update SoundExchange costs (#3070)
updated the minimum SoundExchange royalties for
non-profits/non-commercial

### Description

_Short summary of what is the issue and the solution._

**This is a new feature**:

_Do the changes in this PR implement a new feature?_

**I have updated the documentation to reflect these changes**:

_Are there documentation changes required as a result of these changes?
See
https://github.com/libretime/libretime/wiki/Documentation-Requirements_

### Testing Notes

**What I did:**

_What did you do to validate this PR?_

**How you can replicate my testing:**

_How can the reviewer validate this PR?_

### **Links**

_Issues links or other related resources. Use the line Closes:
#bug_number to
link a bug in the issue tracker._
2024-08-29 08:57:12 +01:00
dakriy 8c26505622
feat(legacy): order by filename when lptime is null (#3069)
### Description

It is good to have a deterministic order when doing explicit file
sorting. This sorts by filename when last played time is null. I would
expect filename to be the next sort after last played time in case of a
tie, and was surprised to find it was not explicit. It should not break
any existing use cases.

**This is a new feature**:

Kind of?

**I have updated the documentation to reflect these changes**:

I did not update any documentation as this way seems like the logical
expected way to do the sort.

### Testing Notes

**What I did:**

I loaded up some tracks into a local libretime instance, let some of
them play, and tested that all the old sorts worked as before as well as
tracks getting sorted by filepath in case of a last played time
2024-08-24 07:47:25 +01:00
dakriy c883d0f2d5
fix(legacy): fix filename criteria searching (#3068)
### Description

The filename criteria searched the full file path and as such does not
work as expected.

**This is a new feature**:

No

**I have updated the documentation to reflect these changes**:

No docs changes are required as this is fixing a bug to make things work
as expected and documented.

### Testing Notes

**What I did:**

I uploaded some files, and tested that the file name criteria worked as
expected.

**How you can replicate my testing:**

Spin up the stack, upload some files and make sure the filename criteria
works as expected.
2024-08-20 22:39:53 +01:00
renovate[bot] f5355d6b61
chore(deps): lock file maintenance (legacy/composer.json) (#3067)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Update | Change |
|---|---|
| lockFileMaintenance | All locks refreshed |

🔧 This Pull Request updates lock files to use the latest dependency
versions.

---

### Configuration

📅 **Schedule**: Branch creation - "after 4am and before 5am on monday"
(UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicGhwIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 12:39:37 +01:00
renovate[bot] fdad983b48
chore(deps): update dependency gunicorn to v23 (#3066)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [gunicorn](https://togithub.com/benoitc/gunicorn)
([changelog](https://docs.gunicorn.org/en/stable/news.html)) |
`>=22.0.0,<22.1` -> `>=22.0.0,<23.1` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/gunicorn/23.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/gunicorn/23.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/gunicorn/22.0.0/23.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gunicorn/22.0.0/23.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>benoitc/gunicorn (gunicorn)</summary>

###
[`v23.0.0`](https://togithub.com/benoitc/gunicorn/releases/tag/23.0.0)

[Compare
Source](https://togithub.com/benoitc/gunicorn/compare/22.0.0...23.0.0)

Gunicorn 23.0.0 has been released. This version fix the numerous
security vulnerabilities. You're invited to upgrade asap your own
installation.

# 23.0.0 - 2024-08-10

-   minor docs fixes (:pr:`3217`, :pr:`3089`, :pr:`3167`)
-   worker_class parameter accepts a class (:pr:`3079`)
- fix deadlock if request terminated during chunked parsing (:pr:`2688`)
- permit receiving Transfer-Encodings: compress, deflate, gzip
(:pr:`3261`)
- permit Transfer-Encoding headers specifying multiple encodings. note:
no parameters, still (:pr:`3261`)
- sdist generation now explicitly excludes sphinx build folder
(:pr:`3257`)
- decode bytes-typed status (as can be passed by gevent) as utf-8
instead of raising `TypeError` (:pr:`2336`)
- raise correct Exception when encounting invalid chunked requests
(:pr:`3258`)
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed
forwarders, are no longer restricted for containing an underscore
(:pr:`3192`)
- include IPv6 loopback address `[::1]` in default for
:ref:`forwarded-allow-ips` and :ref:`proxy-allow-ips` (:pr:`3192`)

\*\* NOTE \*\*

- The SCRIPT_NAME change mitigates a regression that appeared first in
the 22.0.0 release
- Review your :ref:`forwarded-allow-ips` setting if you are still not
seeing the SCRIPT_NAME transmitted
- Review your :ref:`forwarder-headers` setting if you are missing
headers after upgrading from a version prior to 22.0.0

\*\* Breaking changes \*\*

-   refuse requests where the uri field is empty (:pr:`3255`)
- refuse requests with invalid CR/LR/NUL in heade field values
(:pr:`3253`)
- remove temporary `--tolerate-dangerous-framing` switch from 22.0
(:pr:`3260`)
- If any of the breaking changes affect you, be aware that now refused
requests can post a security problem, especially so in setups involving
request pipe-lining and/or proxies.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicHl0aG9uIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 09:11:02 +01:00
renovate[bot] 4b5ab6a2ad
chore(deps): update pre-commit hook psf/black-pre-commit-mirror to v24.8.0 (#3065)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[psf/black-pre-commit-mirror](https://togithub.com/psf/black-pre-commit-mirror)
| repository | minor | `24.4.2` -> `24.8.0` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://togithub.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>psf/black-pre-commit-mirror
(psf/black-pre-commit-mirror)</summary>

###
[`v24.8.0`](https://togithub.com/psf/black-pre-commit-mirror/compare/24.4.2...24.8.0)

[Compare
Source](https://togithub.com/psf/black-pre-commit-mirror/compare/24.4.2...24.8.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-07 16:29:11 +01:00
renovate[bot] 72692c4b77
chore(deps): update dependency django-filter to >=2.4.0,<24.4 (#3060)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [django-filter](https://togithub.com/carltongibson/django-filter)
([changelog](https://togithub.com/carltongibson/django-filter/blob/main/CHANGES.rst))
| `>=2.4.0,<24.3` -> `>=2.4.0,<24.4` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/django-filter/24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/django-filter/24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/django-filter/24.2/24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/django-filter/24.2/24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>carltongibson/django-filter (django-filter)</summary>

###
[`v24.3`](https://togithub.com/carltongibson/django-filter/blob/HEAD/CHANGES.rst#Version-243-2024-08-02)

[Compare
Source](https://togithub.com/carltongibson/django-filter/compare/24.2...24.3)

-   Adds official support for Django 5.1.

-   Allow using dictionaries for grouped choices on Django 5.0+.

    Thanks to Sævar Öfjörð Magnússon.

- Adds `unknown_field_behavior` FilterSet option to allowing warning and
ignore behaviours for unknown field types during FilterSet generation.

    Thanks to Loes.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJweXRob24iXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 12:43:07 +09:00
Kyle Robbertze 1f9a504996
ci: downgrade django-stubs to not install v5.x (#3062)
### Description

This is until upstream fixes
https://github.com/typeddjango/django-stubs/issues/2304
2024-08-04 12:00:56 +09:00
Kyle Robbertze 65d435d9e7
ci: fix broken link check (#3061)
### Description

Ubuntu no longer maintains the package list for bionic. Linked to from
old release notes
2024-08-04 11:47:37 +09:00
renovate[bot] 8136160125
chore(deps): update pre-commit hook asottile/pyupgrade to v3.17.0 (#3059)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [asottile/pyupgrade](https://togithub.com/asottile/pyupgrade) |
repository | minor | `v3.16.0` -> `v3.17.0` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://togithub.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>asottile/pyupgrade (asottile/pyupgrade)</summary>

###
[`v3.17.0`](https://togithub.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0)

[Compare
Source](https://togithub.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-30 10:20:07 +09:00
renovate[bot] 9ee1783afd
chore(deps): update pre-commit hook adamchainz/django-upgrade to v1.20.0 (#3057)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[adamchainz/django-upgrade](https://togithub.com/adamchainz/django-upgrade)
| repository | minor | `1.19.0` -> `1.20.0` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://togithub.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>adamchainz/django-upgrade (adamchainz/django-upgrade)</summary>

###
[`v1.20.0`](https://togithub.com/adamchainz/django-upgrade/blob/HEAD/CHANGELOG.rst#1200-2024-07-19)

[Compare
Source](https://togithub.com/adamchainz/django-upgrade/compare/1.19.0...1.20.0)

- Fix the `admin_register` fixer to avoid rewriting when there are
duplicate `ModelAdmin` classes in the file.

`Issue #&#8203;471
<https://github.com/adamchainz/django-upgrade/issues/471>`\__.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzEuNCIsInVwZGF0ZWRJblZlciI6IjM3LjQzMS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-20 17:48:56 +01:00
Weblate (bot) 482f2215a0
chore(legacy): translations update from Hosted Weblate (#3055)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
2024-07-08 21:20:21 +01:00
Harry W 70735d4431
docs: use new docker compose command (#3054)
Improve the Docker install documentation, along with the `docker
compose` commands.
2024-07-06 10:48:30 +01:00
renovate[bot] e0b1eba1bb chore(deps): update amannn/action-semantic-pull-request action to v5.5.3 2024-06-30 21:04:32 +00:00
Thomas Göttgens e095cb2a5f
fix: docker warnings "keywords casing do not match" (#3048)
### Description

docker wants the 'AS' in uppercase if the 'FROM' is also in uppercase

### Testing Notes

These warnings are eliminated with this patch

``` => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 5)                                                                                                                                    0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 21)                                                                                                                                   0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 51)                                                                                                                                   0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 62)
[...]
```
2024-06-29 20:26:44 +01:00
Weblate (bot) dad3d74188
chore(legacy): translations update from Hosted Weblate (#3046)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for
[LibreTime/Legacy](https://hosted.weblate.org/projects/libretime/legacy/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/libretime/legacy/horizontal-auto.svg)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-06-28 19:23:03 +01:00
renovate[bot] d97c4d427a
chore(deps): update pre-commit hook adamchainz/django-upgrade to v1.19.0 (#3047)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[adamchainz/django-upgrade](https://togithub.com/adamchainz/django-upgrade)
| repository | minor | `1.18.0` -> `1.19.0` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://togithub.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>adamchainz/django-upgrade (adamchainz/django-upgrade)</summary>

###
[`v1.19.0`](https://togithub.com/adamchainz/django-upgrade/blob/HEAD/CHANGELOG.rst#1190-2024-06-27)

[Compare
Source](https://togithub.com/adamchainz/django-upgrade/compare/1.18.0...1.19.0)

- Add Django 4.2+ fixer to rewrite `index_together` declarations into
`indexes` declarations in model `Meta` classes.
    This fixer can make changes that require migrations.
Add a `test for pending migrations
<https://adamj.eu/tech/2024/06/23/django-test-pending-migrations/>`\__
to ensure that you do not miss these.

`PR #&#8203;464
<https://github.com/adamchainz/django-upgrade/pull/464>`\__.

-   Fix tracking of AST node parents.
    This may have fixed some subtle bugs in these fixers:

    -   `admin_register`
    -   `assert_form_error`
    -   `default_app_config`
    -   `management_commands`
    -   `request_headers`
    -   `settings_database_postgresql`
    -   `settings_storages`
    -   `testcase_databases`
    -   `use_l10n`
    -   `utils_timezone`

If you see any new changes, or had them previously disabled, please
report an issue so we can extra tests to the test suite.

`PR #&#8203;465
<https://github.com/adamchainz/django-upgrade/pull/465>`\__.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/libretime/libretime).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MjAuMSIsInVwZGF0ZWRJblZlciI6IjM3LjQyMC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-28 13:59:31 +01:00
renovate[bot] 609b4e7a03 chore(deps): lock file maintenance (legacy/composer.json) 2024-06-25 09:45:08 +00:00
libretime-bot e5aceef71a chore(legacy): update locales 2024-06-24 02:01:54 +00:00
Jonas L 63572fdab9
docs: add missing v4.2.0 release note (#3044)
Forgot to prepare the release note for v4.2.0.
2024-06-22 22:58:15 +02:00
124 changed files with 13557 additions and 7308 deletions

View File

@ -77,7 +77,7 @@ jobs:
working-directory: ${{ inputs.context }}
- name: Report coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
files: ${{ inputs.context }}/coverage.xml
flags: ${{ inputs.context }}

View File

@ -42,7 +42,7 @@ jobs:
- name: Get pull request commit range
if: github.event_name == 'pull_request'
run: echo "COMMIT_RANGE=origin/${{ github.base_ref }}..${{ github.sha }}" >> $GITHUB_ENV
run: echo "COMMIT_RANGE=${{ github.sha }}~1...${{ github.sha }}" >> $GITHUB_ENV
- name: Get push commit range
if: github.event_name == 'push'

View File

@ -76,7 +76,7 @@ jobs:
working-directory: api
- name: Report coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
files: api/coverage.xml
flags: api

View File

@ -48,7 +48,7 @@ jobs:
- name: Check Links
id: lychee
uses: lycheeverse/lychee-action@v1.10.0
uses: lycheeverse/lychee-action@v2.1.0
with:
args: >-
'**/*.md'
@ -62,6 +62,8 @@ jobs:
--exclude 'https://www.ascap.com'
--exclude 'https://www.youtube-nocookie.com'
--exclude 'github\.com/libretime/libretime/(issues|pulls)'
--exclude 'https://packages.ubuntu.com/bionic/php7.2'
--exclude 'https://packages.ubuntu.com/bionic/python3'
--cache
--max-cache-age 2d
fail: true

View File

@ -62,6 +62,7 @@ jobs:
sudo -u postgres psql -c 'CREATE DATABASE libretime;'
sudo -u postgres psql -c "CREATE USER libretime WITH PASSWORD 'libretime';"
sudo -u postgres psql -c 'GRANT CONNECT ON DATABASE libretime TO libretime;'
sudo -u postgres psql -c 'ALTER DATABASE libretime OWNER TO libretime;'
sudo -u postgres psql -c 'ALTER USER libretime CREATEDB;'
- name: Setup PHP

View File

@ -12,7 +12,7 @@ jobs:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5.5.2
- uses: amannn/action-semantic-pull-request@v5.5.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@ -3,7 +3,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
@ -36,13 +36,13 @@ repos:
exclude: ^(legacy/public(?!/js/airtime)|CHANGELOG.md$|.github/release-please-manifest.json)
- repo: https://github.com/asottile/pyupgrade
rev: v3.16.0
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.18.0
rev: 1.22.2
hooks:
- id: django-upgrade
args: [--target-version, "4.2"]
@ -54,7 +54,7 @@ repos:
args: [--resolve-all-configs]
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.4.2
rev: 24.10.0
hooks:
- id: black
@ -110,3 +110,11 @@ repos:
pass_filenames: false
language: script
files: ^legacy
- id: api-schema-update
name: api-schema-update
description: Ensure API schema is up to date
entry: make -C api schema
pass_filenames: false
language: system
files: ^api

View File

@ -2,7 +2,7 @@ ARG LIBRETIME_VERSION
#======================================================================================#
# Python Builder #
#======================================================================================#
FROM python:3.10-slim-bullseye as python-builder
FROM python:3.10-slim-bullseye AS python-builder
WORKDIR /build
@ -18,7 +18,7 @@ RUN pip wheel --wheel-dir . --no-deps .
#======================================================================================#
# Python base #
#======================================================================================#
FROM python:3.10-slim-bullseye as python-base
FROM python:3.10-slim-bullseye AS python-base
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
@ -48,7 +48,7 @@ RUN set -eux \
#======================================================================================#
# Python base with ffmpeg #
#======================================================================================#
FROM python-base as python-base-ffmpeg
FROM python-base AS python-base-ffmpeg
RUN set -eux \
&& DEBIAN_FRONTEND=noninteractive apt-get update \
@ -59,7 +59,7 @@ RUN set -eux \
#======================================================================================#
# Analyzer #
#======================================================================================#
FROM python-base-ffmpeg as libretime-analyzer
FROM python-base-ffmpeg AS libretime-analyzer
COPY tools/packages.py /tmp/packages.py
COPY analyzer/packages.ini /tmp/packages.ini
@ -97,7 +97,7 @@ ENV LIBRETIME_VERSION=$LIBRETIME_VERSION
#======================================================================================#
# Playout #
#======================================================================================#
FROM python-base-ffmpeg as libretime-playout
FROM python-base-ffmpeg AS libretime-playout
COPY tools/packages.py /tmp/packages.py
COPY playout/packages.ini /tmp/packages.ini
@ -136,7 +136,7 @@ ENV LIBRETIME_VERSION=$LIBRETIME_VERSION
#======================================================================================#
# API #
#======================================================================================#
FROM python-base as libretime-api
FROM python-base AS libretime-api
RUN set -eux \
&& DEBIAN_FRONTEND=noninteractive apt-get update \
@ -180,7 +180,7 @@ HEALTHCHECK CMD ["curl", "--fail", "http://localhost:9001/api/v2/version"]
#======================================================================================#
# Worker #
#======================================================================================#
FROM python-base as libretime-worker
FROM python-base AS libretime-worker
WORKDIR /src
@ -208,7 +208,7 @@ ENV LIBRETIME_VERSION=$LIBRETIME_VERSION
#======================================================================================#
# Legacy #
#======================================================================================#
FROM php:7.4-fpm as libretime-legacy
FROM php:7.4-fpm AS libretime-legacy
ENV LIBRETIME_CONFIG_FILEPATH=/etc/libretime/config.yml
ENV LIBRETIME_LOG_FILEPATH=php://stderr

View File

@ -22,10 +22,10 @@ dev-certs:
cat dev/certs/fake.{key,crt} > dev/certs/fake.pem
dev: .env dev-certs
DOCKER_BUILDKIT=1 docker-compose build
docker-compose run --rm legacy make build
docker-compose run --rm api libretime-api migrate
docker-compose up -d
DOCKER_BUILDKIT=1 docker compose build
docker compose run --rm legacy make build
docker compose run --rm api libretime-api migrate
docker compose up -d
.PHONY: VERSION
VERSION:

View File

@ -75,8 +75,7 @@ def compute_silences(filepath: Path) -> List[Tuple[float, float]]:
cmd = _ffmpeg(
*("-i", filepath),
"-vn",
*("-filter", "highpass=frequency=1000"),
*("-filter", "silencedetect=noise=0.15:duration=1"),
*("-filter", "highpass=frequency=80,silencedetect=noise=-60dB:duration=0.9"),
)
starts, ends = [], []

View File

@ -5,10 +5,24 @@ from typing import Any, Dict
import mutagen
from libretime_shared.files import compute_md5
from mutagen.easyid3 import EasyID3
logger = logging.getLogger(__name__)
def flatten(xss):
return [x for xs in xss for x in xs]
def comment_get(id3, _):
comments = [v.text for k, v in id3.items() if "COMM" in k or "comment" in k]
return flatten(comments)
EasyID3.RegisterKey("comment", comment_get)
def analyze_metadata(filepath_: str, metadata: Dict[str, Any]):
"""
Extract audio metadata from tags embedded in the file using mutagen.
@ -71,34 +85,36 @@ def analyze_metadata(filepath_: str, metadata: Dict[str, Any]):
except (AttributeError, KeyError, IndexError):
pass
extracted_tags_mapping = {
"title": "track_title",
"artist": "artist_name",
"album": "album_title",
"bpm": "bpm",
"composer": "composer",
"conductor": "conductor",
"copyright": "copyright",
"comment": "comment",
"encoded_by": "encoder",
"genre": "genre",
"isrc": "isrc",
"label": "label",
"organization": "label",
# "length": "length",
"language": "language",
"last_modified": "last_modified",
"mood": "mood",
"bit_rate": "bit_rate",
"replay_gain": "replaygain",
# "tracknumber": "track_number",
# "track_total": "track_total",
"website": "website",
"date": "year",
# "mime_type": "mime",
}
extracted_tags_mapping = [
("title", "track_title"),
("artist", "artist_name"),
("album", "album_title"),
("bpm", "bpm"),
("composer", "composer"),
("conductor", "conductor"),
("copyright", "copyright"),
("comment", "comment"),
("comment", "comments"),
("comment", "description"),
("encoded_by", "encoder"),
("genre", "genre"),
("isrc", "isrc"),
("label", "label"),
("organization", "label"),
# ("length", "length"),
("language", "language"),
("last_modified", "last_modified"),
("mood", "mood"),
("bit_rate", "bit_rate"),
("replay_gain", "replaygain"),
# ("tracknumber", "track_number"),
# ("track_total", "track_total"),
("website", "website"),
("date", "year"),
# ("mime_type", "mime"),
]
for extracted_key, metadata_key in extracted_tags_mapping.items():
for extracted_key, metadata_key in extracted_tags_mapping:
try:
metadata[metadata_key] = extracted[extracted_key]
if isinstance(metadata[metadata_key], list):

View File

@ -23,28 +23,28 @@ FILES = [
# 8s -> 9s: silence
# 9s -> 12s: musik
# 12s -> 15s: pink noise fade out
Fixture(here / "s1-jointstereo.mp3", 15.0, 6.0, 13.0, -5.9 ),
Fixture(here / "s1-mono.mp3", 15.0, 6.0, 13.0, -2.0 ),
Fixture(here / "s1-stereo.mp3", 15.0, 6.0, 13.0, -5.9 ),
Fixture(here / "s1-mono-12.mp3", 15.0, 9.0, 12.0, +7.0 ),
Fixture(here / "s1-stereo-12.mp3", 15.0, 9.0, 12.0, +6.1 ),
Fixture(here / "s1-mono+12.mp3", 15.0, 3.5, 13.0, -17.0 ),
Fixture(here / "s1-stereo+12.mp3", 15.0, 3.5, 13.0, -17.8 ),
Fixture(here / "s1-mono.flac", 15.0, 6.0, 13.0, -2.3 ),
Fixture(here / "s1-stereo.flac", 15.0, 6.0, 13.0, -6.0 ),
Fixture(here / "s1-mono-12.flac", 15.0, 9.0, 12.0, +10.0 ),
Fixture(here / "s1-stereo-12.flac", 15.0, 9.0, 12.0, +5.9 ),
Fixture(here / "s1-mono+12.flac", 15.0, 3.5, 13.0, -12.0 ),
Fixture(here / "s1-stereo+12.flac", 15.0, 3.5, 13.0, -14.9 ),
Fixture(here / "s1-mono.m4a", 15.0, 6.0, 13.0, -4.5 ),
Fixture(here / "s1-stereo.m4a", 15.0, 6.0, 13.0, -5.8 ),
Fixture(here / "s1-mono.ogg", 15.0, 6.0, 13.0, -4.9 ),
Fixture(here / "s1-stereo.ogg", 15.0, 6.0, 13.0, -5.7 ),
Fixture(here / "s1-stereo", 15.0, 6.0, 13.0, -5.7 ),
Fixture(here / "s1-mono.wav", 15.0, 6.0, 13.0, -2.3 ),
Fixture(here / "s1-stereo.wav", 15.0, 6.0, 13.0, -6.0 ),
Fixture(here / "s1-jointstereo.mp3", 15.0, 1.4, 15.0, -5.9 ),
Fixture(here / "s1-mono.mp3", 15.0, 1.5, 15.0, -2.0 ),
Fixture(here / "s1-stereo.mp3", 15.0, 1.4, 15.0, -5.9 ),
Fixture(here / "s1-mono-12.mp3", 15.0, 1.2, 15.0, +7.0 ),
Fixture(here / "s1-stereo-12.mp3", 15.0, 1.2, 15.0, +6.1 ),
Fixture(here / "s1-mono+12.mp3", 15.0, 1.2, 15.0, -17.0 ),
Fixture(here / "s1-stereo+12.mp3", 15.0, 1.2, 15.0, -17.8 ),
Fixture(here / "s1-mono.flac", 15.0, 1.4, 15.0, -2.3 ),
Fixture(here / "s1-stereo.flac", 15.0, 1.4, 15.0, -6.0 ),
Fixture(here / "s1-mono-12.flac", 15.0, 2.0, 15.0, +10.0 ),
Fixture(here / "s1-stereo-12.flac", 15.0, 1.8, 15.0, +5.9 ),
Fixture(here / "s1-mono+12.flac", 15.0, 0.0, 15.0, -12.0 ),
Fixture(here / "s1-stereo+12.flac", 15.0, 0.0, 15.0, -14.9 ),
Fixture(here / "s1-mono.m4a", 15.0, 1.4, 15.0, -4.5 ),
Fixture(here / "s1-stereo.m4a", 15.0, 1.4, 15.0, -5.8 ),
Fixture(here / "s1-mono.ogg", 15.0, 1.4, 15.0, -4.9 ),
Fixture(here / "s1-stereo.ogg", 15.0, 1.4, 15.0, -5.7 ),
Fixture(here / "s1-stereo", 15.0, 1.4, 15.0, -5.7 ),
Fixture(here / "s1-mono.wav", 15.0, 1.5, 15.0, -2.3 ),
Fixture(here / "s1-stereo.wav", 15.0, 1.4, 15.0, -6.0 ),
# sample 1 large (looped for 2 hours)
Fixture(here / "s1-large.flac", 7200, 6.0, 7198, -6.0 ),
Fixture(here / "s1-large.flac", 7200, 1.4, 7200, -6.0 ),
# sample 2
# 0s -> 1.8s: silence
# 1.8s : noise
@ -96,12 +96,18 @@ tags = {
"comment": "Test Comment",
}
mp3Tags = {
**tags,
"comments": tags["comment"],
"description": tags["comment"],
}
FILES_TAGGED = [
FixtureMeta(
here / "s1-jointstereo-tagged.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e2),
"channels": 2,
"mime": "audio/mp3",
@ -111,7 +117,7 @@ FILES_TAGGED = [
here / "s1-mono-tagged.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(64000, abs=1e2),
"channels": 1,
"mime": "audio/mp3",
@ -121,7 +127,7 @@ FILES_TAGGED = [
here / "s1-stereo-tagged.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e2),
"channels": 2,
"mime": "audio/mp3",
@ -151,7 +157,7 @@ FILES_TAGGED = [
here / "s1-mono-tagged.m4a",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(65000, abs=5e4),
"channels": 2, # Weird
"mime": "audio/mp4",
@ -161,7 +167,7 @@ FILES_TAGGED = [
here / "s1-stereo-tagged.m4a",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e5),
"channels": 2,
"mime": "audio/mp4",
@ -228,12 +234,18 @@ tags = {
"comment": "Ł Ą Ż Ę Ć Ń Ś Ź",
}
mp3Tags = {
**tags,
"comments": tags["comment"],
"description": tags["comment"],
}
FILES_TAGGED += [
FixtureMeta(
here / "s1-jointstereo-tagged-utf8.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e2),
"channels": 2,
"mime": "audio/mp3",
@ -243,7 +255,7 @@ FILES_TAGGED += [
here / "s1-mono-tagged-utf8.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(64000, abs=1e2),
"channels": 1,
"mime": "audio/mp3",
@ -253,7 +265,7 @@ FILES_TAGGED += [
here / "s1-stereo-tagged-utf8.mp3",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e2),
"channels": 2,
"mime": "audio/mp3",
@ -283,7 +295,7 @@ FILES_TAGGED += [
here / "s1-mono-tagged-utf8.m4a",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(65000, abs=5e4),
"channels": 2, # Weird
"mime": "audio/mp4",
@ -293,7 +305,7 @@ FILES_TAGGED += [
here / "s1-stereo-tagged-utf8.m4a",
{
**meta,
**tags,
**mp3Tags,
"bit_rate": approx(128000, abs=1e5),
"channels": 2,
"mime": "audio/mp4",

View File

@ -27,8 +27,8 @@ def test_analyze_metadata(filepath: Path, metadata: dict):
del metadata["length"]
del found["length"]
# mp3,ogg,flac files does not support comments yet
if not filepath.suffix == ".m4a":
# ogg,flac files does not support comments yet
if not filepath.suffix == ".m4a" and not filepath.suffix == ".mp3":
if "comment" in metadata:
del metadata["comment"]

View File

@ -8,6 +8,7 @@ from .role import Role
class UserManager(BaseUserManager):
# pylint: disable=too-many-positional-arguments
def create_user(self, role, username, password, email, first_name, last_name):
user = self.model(
role=role,
@ -20,6 +21,7 @@ class UserManager(BaseUserManager):
user.save(using=self._db)
return user
# pylint: disable=too-many-positional-arguments
def create_superuser(self, username, password, email, first_name, last_name):
return self.create_user(
Role.ADMIN,

View File

@ -8,8 +8,6 @@ UP = """
-- DELETE FROM cc_pref WHERE keystr = 'system_version';
-- INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.5.5');
ALTER TABLE cc_show ADD COLUMN image_path varchar(255) DEFAULT '';
ALTER TABLE cc_show_instances ADD COLUMN description varchar(255) DEFAULT '';
"""
DOWN = None

View File

@ -5,7 +5,7 @@ from django.db import migrations
from ._migrations import legacy_migration_factory
UP = """
ALTER TABLE cc_files ADD COLUMN artwork TYPE character varying(255);
ALTER TABLE cc_files ADD COLUMN artwork VARCHAR(255);
"""
DOWN = None

View File

@ -4,12 +4,18 @@ from django.db import migrations
from ._migrations import legacy_migration_factory
# This migration is currently a placeholder for 3.0.0-alpha.9.1.
# Please do not remove it. There are currently no actions, but it
# needs to remain intact so it does not fail when called from the
# migrations script. Any future migrations that may apply to
# 3.0.0-alpha.9.1 will be added to this file.
UP = """
ALTER TABLE cc_files ADD COLUMN artwork VARCHAR(4096);
"""
DOWN = """
ALTER TABLE cc_files DROP COLUMN IF EXISTS artwork;
"""

View File

@ -0,0 +1,37 @@
# pylint: disable=invalid-name
from django.db import migrations
from ._migrations import legacy_migration_factory
UP = """
ALTER TABLE cc_show ADD COLUMN override_intro_playlist boolean default 'f' NOT NULL;
ALTER TABLE cc_show ADD COLUMN intro_playlist_id integer DEFAULT NULL;
ALTER TABLE cc_show ADD CONSTRAINT cc_playlist_intro_playlist_fkey FOREIGN KEY (intro_playlist_id) REFERENCES cc_playlist (id) ON DELETE SET NULL;
ALTER TABLE cc_show ADD COLUMN override_outro_playlist boolean default 'f' NOT NULL;
ALTER TABLE cc_show ADD COLUMN outro_playlist_id integer DEFAULT NULL;
ALTER TABLE cc_show ADD CONSTRAINT cc_playlist_outro_playlist_fkey FOREIGN KEY (outro_playlist_id) REFERENCES cc_playlist (id) ON DELETE SET NULL;
"""
DOWN = """
ALTER TABLE cc_show DROP COLUMN IF EXISTS override_intro_playlist;
ALTER TABLE cc_show DROP COLUMN IF EXISTS intro_playlist_id;
ALTER TABLE cc_show DROP CONSTRAINT IF EXISTS cc_playlist_intro_playlist_fkey;
ALTER TABLE cc_show DROP COLUMN IF EXISTS override_outro_playlist;
ALTER TABLE cc_show DROP COLUMN IF EXISTS outro_playlist_id;
ALTER TABLE cc_show DROP CONSTRAINT IF EXISTS cc_playlist_outro_playlist_fkey;
"""
class Migration(migrations.Migration):
dependencies = [
("legacy", "0045_add_sessions_table"),
]
operations = [
migrations.RunPython(
code=legacy_migration_factory(
target="46",
sql=UP,
)
)
]

View File

@ -1,2 +1,2 @@
# The schema version is defined using the migration file prefix number
LEGACY_SCHEMA_VERSION = "45"
LEGACY_SCHEMA_VERSION = "46"

View File

@ -11,15 +11,28 @@ def get_schema_version():
Don't use django models as they might break in the future. Our concern is to upgrade
the legacy database schema to the point where django is in charge of the migrations.
An airtime 2.5.1 migration will not have schema_version, in that case, we look for
system_version to have a value of 2.5.1 and return that as the schema version value
(really just needs to be anything besides None, so that the next migration doesn't overwrite
the database)
"""
if "cc_pref" not in connection.introspection.table_names():
return None
with connection.cursor() as cursor:
cursor.execute("SELECT valstr FROM cc_pref WHERE keystr = 'schema_version'")
cursor.execute(
"""
SELECT valstr AS version
FROM cc_pref
WHERE (keystr = 'schema_version') OR (keystr = 'system_version' AND valstr = '2.5.1')
"""
)
row = cursor.fetchone()
return row[0] if row else None
if row and row[0]:
return row[0]
return None
def set_schema_version(cursor, version: str):

View File

@ -126,6 +126,10 @@ CREATE TABLE "cc_show"
"has_autoplaylist" BOOLEAN DEFAULT 'f' NOT NULL,
"autoplaylist_id" INTEGER,
"autoplaylist_repeat" BOOLEAN DEFAULT 'f' NOT NULL,
"override_intro_playlist" BOOLEAN DEFAULT 'f' NOT NULL,
"intro_playlist_id" INTEGER,
"override_outro_playlist" BOOLEAN DEFAULT 'f' NOT NULL,
"outro_playlist_id" INTEGER,
PRIMARY KEY ("id")
);
@ -718,6 +722,16 @@ ALTER TABLE "cc_show" ADD CONSTRAINT "cc_playlist_autoplaylist_fkey"
REFERENCES "cc_playlist" ("id")
ON DELETE SET NULL;
ALTER TABLE "cc_show" ADD CONSTRAINT "cc_playlist_intro_playlist_fkey"
FOREIGN KEY ("intro_playlist_id")
REFERENCES "cc_playlist" ("id")
ON DELETE SET NULL;
ALTER TABLE "cc_show" ADD CONSTRAINT "cc_playlist_outro_playlist_fkey"
FOREIGN KEY ("outro_playlist_id")
REFERENCES "cc_playlist" ("id")
ON DELETE SET NULL;
ALTER TABLE "cc_show_instances" ADD CONSTRAINT "cc_show_fkey"
FOREIGN KEY ("show_id")
REFERENCES "cc_show" ("id")

View File

@ -0,0 +1 @@
from .readwriteserializer import ReadWriteSerializerMixin

View File

@ -0,0 +1,33 @@
from rest_framework.serializers import Serializer
class ReadWriteSerializerMixin:
"""
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
"""
read_serializer_class = Serializer
write_serializer_class = Serializer
def get_serializer_class(self):
if self.action in ["create"]:
return self.get_write_serializer_class()
return self.get_read_serializer_class()
def get_read_serializer_class(self):
assert self.read_serializer_class is not None, (
f"'{self.__class__.__name__}' should either include a `read_serializer_class`"
"attribute, or override the `get_read_serializer_class()` method."
)
return self.read_serializer_class
def get_write_serializer_class(self):
assert self.write_serializer_class is not None, (
f"'{self.__class__.__name__}' should either include a `write_serializer_class`"
"attribute, or override the `get_write_serializer_class()` method."
)
return self.write_serializer_class

View File

@ -69,6 +69,28 @@ class Show(models.Model):
auto_playlist_enabled = models.BooleanField(db_column="has_autoplaylist")
auto_playlist_repeat = models.BooleanField(db_column="autoplaylist_repeat")
intro_playlist = models.ForeignKey(
"schedule.Playlist",
on_delete=models.DO_NOTHING,
blank=True,
null=True,
db_column="intro_playlist_id",
related_name="intro_playlist",
)
override_intro_playlist = models.BooleanField(db_column="override_intro_playlist")
outro_playlist = models.ForeignKey(
"schedule.Playlist",
on_delete=models.DO_NOTHING,
blank=True,
null=True,
db_column="outro_playlist_id",
related_name="outro_playlist",
)
override_outro_playlist = models.BooleanField(db_column="override_outro_playlist")
hosts = models.ManyToManyField( # type: ignore[var-annotated]
"core.User",
through="ShowHost",

View File

@ -1,5 +1,5 @@
from .playlist import PlaylistContentSerializer, PlaylistSerializer
from .schedule import ScheduleSerializer
from .schedule import ReadScheduleSerializer, WriteScheduleSerializer
from .show import (
ShowDaysSerializer,
ShowHostSerializer,

View File

@ -3,10 +3,17 @@ from rest_framework import serializers
from ..models import Schedule
class ScheduleSerializer(serializers.ModelSerializer):
class ReadScheduleSerializer(serializers.ModelSerializer):
cue_out = serializers.DurationField(source="get_cue_out", read_only=True)
ends_at = serializers.DateTimeField(source="get_ends_at", read_only=True)
class Meta:
model = Schedule
fields = "__all__"
class WriteScheduleSerializer(serializers.ModelSerializer):
class Meta:
model = Schedule
fields = "__all__"

View File

@ -21,6 +21,10 @@ class ShowSerializer(serializers.ModelSerializer):
"auto_playlist",
"auto_playlist_enabled",
"auto_playlist_repeat",
"intro_playlist",
"override_intro_playlist",
"outro_playlist",
"override_outro_playlist",
]

View File

@ -2,8 +2,9 @@ from django.db import models
from django_filters import rest_framework as filters
from rest_framework import viewsets
from ...mixins import ReadWriteSerializerMixin
from ..models import Schedule
from ..serializers import ScheduleSerializer
from ..serializers import ReadScheduleSerializer, WriteScheduleSerializer
class ScheduleFilter(filters.FilterSet):
@ -26,8 +27,9 @@ class ScheduleFilter(filters.FilterSet):
fields = [] # type: ignore
class ScheduleViewSet(viewsets.ModelViewSet):
class ScheduleViewSet(ReadWriteSerializerMixin, viewsets.ModelViewSet):
queryset = Schedule.objects.all()
serializer_class = ScheduleSerializer
read_serializer_class = ReadScheduleSerializer
write_serializer_class = WriteScheduleSerializer
filterset_class = ScheduleFilter
model_permission_name = "schedule"

View File

@ -61,3 +61,36 @@ class TestFileViewSet(APITestCase):
file_id = "1"
response = self.client.delete(f"/api/v2/files/{file_id}")
self.assertEqual(response.status_code, 404)
def test_filters(self):
file = baker.make(
"storage.File",
mime="audio/mp3",
filepath=AUDIO_FILENAME,
genre="Soul",
md5="5a11ffe0e6c6d70fcdbad1b734be6482",
)
baker.make(
"storage.File",
mime="audio/mp3",
filepath=AUDIO_FILENAME,
genre="R&B",
md5="5a11ffe0e6c6d70fcdbad1b734be6483",
)
self.client.credentials(HTTP_AUTHORIZATION=f"Api-Key {self.token}")
path = "/api/v2/files"
results = self.client.get(path).json()
self.assertEqual(len(results), 2)
path = f"/api/v2/files?md5={file.md5}"
results = self.client.get(path).json()
self.assertEqual(len(results), 1)
path = "/api/v2/files?genre=Soul"
results = self.client.get(path).json()
self.assertEqual(len(results), 1)
path = "/api/v2/files?genre=R%26B"
results = self.client.get(path).json()
self.assertEqual(len(results), 1)

View File

@ -5,6 +5,7 @@ from os import remove
from django.conf import settings
from django.http import HttpResponse
from django.utils.encoding import filepath_to_uri
from django_filters import rest_framework as filters
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import APIException
@ -26,6 +27,8 @@ class FileViewSet(viewsets.ModelViewSet):
queryset = File.objects.all()
serializer_class = FileSerializer
model_permission_name = "file"
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ("md5", "genre")
# pylint: disable=invalid-name,unused-argument
@action(detail=True, methods=["GET"])

View File

@ -1,11 +1,11 @@
# Please do not edit this file, edit the setup.py file!
# This file is auto-generated by tools/extract_requirements.py.
django-cors-headers>=3.14.0,<4.5
django-filter>=2.4.0,<24.3
django-filter>=2.4.0,<24.4
django>=4.2.0,<4.3
djangorestframework>=3.14.0,<3.16
drf-spectacular>=0.22.1,<0.28
gunicorn>=22.0.0,<22.1
drf-spectacular>=0.22.1,<0.29
gunicorn>=22.0.0,<23.1
psycopg[c]>=3.1.8,<3.2
requests>=2.32.2,<2.33
uvicorn[standard]>=0.17.6,<0.31.0
uvicorn[standard]>=0.17.6,<0.33.0

View File

@ -154,6 +154,15 @@ paths:
/api/v2/files:
get:
operationId: files_list
parameters:
- in: query
name: genre
schema:
type: string
- in: query
name: md5
schema:
type: string
tags:
- files
security:
@ -2552,6 +2561,12 @@ paths:
/api/v2/schedule:
get:
operationId: schedule_list
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
parameters:
- in: query
name: broadcasted
@ -2597,23 +2612,29 @@ paths:
schema:
type: array
items:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
description: ""
post:
operationId: schedule_create
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
tags:
- schedule
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/WriteSchedule"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/WriteSchedule"
multipart/form-data:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/WriteSchedule"
required: true
security:
- cookieAuth: []
@ -2623,11 +2644,17 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/WriteSchedule"
description: ""
/api/v2/schedule/{id}:
get:
operationId: schedule_retrieve
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
parameters:
- in: path
name: id
@ -2645,10 +2672,16 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
description: ""
put:
operationId: schedule_update
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
parameters:
- in: path
name: id
@ -2662,13 +2695,13 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
multipart/form-data:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
required: true
security:
- cookieAuth: []
@ -2678,10 +2711,16 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
description: ""
patch:
operationId: schedule_partial_update
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
parameters:
- in: path
name: id
@ -2695,13 +2734,13 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/PatchedSchedule"
$ref: "#/components/schemas/PatchedReadSchedule"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/PatchedSchedule"
$ref: "#/components/schemas/PatchedReadSchedule"
multipart/form-data:
schema:
$ref: "#/components/schemas/PatchedSchedule"
$ref: "#/components/schemas/PatchedReadSchedule"
security:
- cookieAuth: []
- basicAuth: []
@ -2710,10 +2749,16 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
$ref: "#/components/schemas/ReadSchedule"
description: ""
delete:
operationId: schedule_destroy
description: |-
Overrides get_serializer_class to choose the read serializer
for GET requests and the write serializer for POST requests.
Set read_serializer_class and write_serializer_class attributes on a
viewset.
parameters:
- in: path
name: id
@ -6300,7 +6345,7 @@ components:
user:
type: integer
nullable: true
PatchedSchedule:
PatchedReadSchedule:
type: object
properties:
id:
@ -6409,6 +6454,16 @@ components:
type: boolean
auto_playlist_repeat:
type: boolean
intro_playlist:
type: integer
nullable: true
override_intro_playlist:
type: boolean
outro_playlist:
type: integer
nullable: true
override_outro_playlist:
type: boolean
PatchedShowDays:
type: object
properties:
@ -7086,41 +7141,7 @@ components:
- id
- key
- user
RecordEnabledEnum:
enum:
- 0
- 1
type: integer
description: |-
* `0` - No
* `1` - Yes
RepeatKindEnum:
enum:
- 0
- 1
- 4
- 5
- 2
type: integer
description: |-
* `0` - Every week
* `1` - Every 2 weeks
* `4` - Every 3 weeks
* `5` - Every 4 weeks
* `2` - Every month
RoleEnum:
enum:
- G
- H
- P
- A
type: string
description: |-
* `G` - Guest
* `H` - Host
* `P` - Manager
* `A` - Admin
Schedule:
ReadSchedule:
type: object
properties:
id:
@ -7182,6 +7203,40 @@ components:
- instance
- position
- starts_at
RecordEnabledEnum:
enum:
- 0
- 1
type: integer
description: |-
* `0` - No
* `1` - Yes
RepeatKindEnum:
enum:
- 0
- 1
- 4
- 5
- 2
type: integer
description: |-
* `0` - Every week
* `1` - Every 2 weeks
* `4` - Every 3 weeks
* `5` - Every 4 weeks
* `2` - Every month
RoleEnum:
enum:
- G
- H
- P
- A
type: string
description: |-
* `G` - Guest
* `H` - Host
* `P` - Manager
* `A` - Admin
ServiceRegister:
type: object
properties:
@ -7241,6 +7296,16 @@ components:
type: boolean
auto_playlist_repeat:
type: boolean
intro_playlist:
type: integer
nullable: true
override_intro_playlist:
type: boolean
outro_playlist:
type: integer
nullable: true
override_outro_playlist:
type: boolean
required:
- auto_playlist_enabled
- auto_playlist_repeat
@ -7249,6 +7314,8 @@ components:
- linked
- live_enabled
- name
- override_intro_playlist
- override_outro_playlist
ShowDays:
type: object
properties:
@ -7773,6 +7840,66 @@ components:
* `4` - Friday
* `5` - Saturday
* `6` - Sunday
WriteSchedule:
type: object
properties:
id:
type: integer
readOnly: true
starts_at:
type: string
format: date-time
ends_at:
type: string
format: date-time
length:
type: string
nullable: true
fade_in:
type: string
format: time
nullable: true
fade_out:
type: string
format: time
nullable: true
cue_in:
type: string
cue_out:
type: string
position:
type: integer
maximum: 2147483647
minimum: -2147483648
position_status:
allOf:
- $ref: "#/components/schemas/PositionStatusEnum"
minimum: -32768
maximum: 32767
broadcasted:
type: integer
maximum: 32767
minimum: -32768
played:
type: boolean
nullable: true
instance:
type: integer
file:
type: integer
nullable: true
stream:
type: integer
nullable: true
required:
- broadcasted
- cue_in
- cue_out
- ends_at
- id
- instance
- position
- starts_at
securitySchemes:
basicAuth:
type: http

View File

@ -27,21 +27,21 @@ setup(
},
install_requires=[
"django-cors-headers>=3.14.0,<4.5",
"django-filter>=2.4.0,<24.3",
"django-filter>=2.4.0,<24.4",
"django>=4.2.0,<4.3",
"djangorestframework>=3.14.0,<3.16",
"drf-spectacular>=0.22.1,<0.28",
"drf-spectacular>=0.22.1,<0.29",
"requests>=2.32.2,<2.33",
],
extras_require={
"prod": [
"gunicorn>=22.0.0,<22.1",
"gunicorn>=22.0.0,<23.1",
"psycopg[c]>=3.1.8,<3.2",
"uvicorn[standard]>=0.17.6,<0.31.0",
"uvicorn[standard]>=0.17.6,<0.33.0",
],
"dev": [
"django-coverage-plugin>=3.0.0,<4",
"django-stubs>=1.14.0,<6",
"django-stubs>=5.1.0,<6",
"djangorestframework-stubs>=1.8.0,<4",
"model_bakery>=1.10.1,<2",
"psycopg[binary]>=3.1.8,<4",

View File

@ -113,3 +113,68 @@ general:
```
You should now be able to use your FreeIPA credentials to log in to LibreTime.
## Setup Header Authentication
If you have an SSO system that supports trusted SSO header authentication such as [Authelia](https://www.authelia.com/),
you can configure LibreTime to login users based on those trusted headers.
This allows users to only need to log in once on the SSO system and not need to log in again. It also allows LibreTime
to indirectly support other authentication mechanisms such as OAuth2.
This ONLY affects Legacy/Legacy API auth and does NOT affect API V2 auth.
### Configure Headers
LibreTime needs to know what headers are sent, and what information is available to it. You can also
setup a predefined group mapping so users are automatically granted the desired permissions.
This configuration is in `/etc/libretime/config.yml`. The following is an example configuration for an SSO service
that does the following:
- Sends the username in the `Remote-User` HTTP header.
- Sends the email in the `Remote-Email` HTTP header.
- Sends the name in the `Remote-Name` HTTP header. Example `John Doe`
- Sends the comma delimited groups in the `Remote-Groups` HTTP header. Example `group 1,lt-admin,group2`
- Has an IP of `10.0.0.34` (not required). When not provided it is not checked.
- Users with the `lt-host` group should get host privileges.
- Users with the `lt-admin` group should get admin privileges.
- Users with the `lt-pm` group should get program manager privileges.
- Users with the `lt-superadmin` group should get super admin privileges.
- All other users should get guest privileges.
```yml
header_auth:
user_header: Remote-User # This is the default and could be omitted
groups_header: Remote-Groups # This is the default and could be omitted
email_header: Remote-Email # This is the default and could be omitted
name_header: Remote-Name # This is the default and could be omitted
proxy_ip: 10.0.0.34
group_map:
host: lt-host
program_manager: lt-pm
admin: lt-admin
superadmin: lt-superadmin
```
If the `user_header` is not found in the request, users will be kicked to the login page
with a message that their username/password is invalid and will not be able to log in. When `proxy_ip` is provided
it will check that the request is coming from the correct proxy before doing the login. This prevents users who have
internal network access from being able to login as whoever they want in LibreTime.
::: warning
If `proxy_ip` is not provided any user on the internal network can log in as any user in LibreTime.
:::
### Enable Header authentication
After everything is set up properly you can enable header auth in `config.yml`:
```yml
general:
auth: LibreTime_Auth_Adaptor_Header
```
You should now be automatically logged into LibreTime when you click the `Login` button.

View File

@ -22,7 +22,7 @@ First, set the version you want to install:
echo LIBRETIME_VERSION="{vars.version}" > .env
</CodeBlock>
Download the docker-compose files from the repository:
Download the docker compose files from the repository:
```bash
# Load LIBRETIME_VERSION variable
@ -106,16 +106,16 @@ You can find more details in the `docker-compose.yml` file or on the external se
Next, run the following commands to setup the database:
```bash
docker-compose run --rm api libretime-api migrate
docker compose run --rm api libretime-api migrate
```
Finally, start the services, and check that they're running using the following commands:
```bash
docker-compose up -d
docker compose up -d
docker-compose ps
docker-compose logs -f
docker compose ps
docker compose logs -f
```
## Securing LibreTime

View File

@ -54,7 +54,7 @@ liable to legal action.
If you want to go down the commercial music route, check out the
https://www.prsformusic.com and https://www.ppluk.com websites for UK licence
details. In the USA, the https://www.soundexchange.com website currently quotes
a 500 dollar minimum annual fee for non-commercial webcasters, plus a usage fee
a 1000 (per Jan. 2024) dollar minimum annual fee for non-commercial webcasters, plus a usage fee
above a certain number of listener hours, for the right to stream music
recordings to listeners. See the websites of [ASCAP](https://www.ascap.com),
[BMI](https://www.bmi.com) and [SESAC](https://www.sesac.com) for details of music

View File

@ -14,16 +14,16 @@ To setup a docker-compose development environment, run the following commands:
# Clean and build
make clean
cp .env.dev .env
DOCKER_BUILDKIT=1 docker-compose build
DOCKER_BUILDKIT=1 docker compose build
# Setup
make dev-certs
docker-compose run --rm legacy make build
docker-compose run --rm api libretime-api migrate
docker compose run --rm legacy make build
docker compose run --rm api libretime-api migrate
# Run
docker-compose up -d
docker-compose logs -f
docker compose up -d
docker compose logs -f
```
:::info
@ -33,7 +33,7 @@ You may also use the following `make clean dev` shortcut:
```bash
make clean dev
docker-compose logs -f
docker compose logs -f
```
:::

25
docs/releases/4.2.0.md Normal file
View File

@ -0,0 +1,25 @@
---
title: LibreTime 4.2.0
---
import ReleaseHead from './\_release-head.md';
<ReleaseHead date='2024-06-22' version='4.2.0'/>
## :sparkling_heart: Contributors
The LibreTime project wants to thank the following contributors for authoring PRs to this release:
- @conet
- @dakriy
- @jooola
- @paddatrapper
- @rjhelms
## :rocket: Features
Please see the [changelog](https://github.com/libretime/libretime/blob/main/CHANGELOG.md#420-2024-06-22).
## :bug: Bug fixes
Please see the [changelog](https://github.com/libretime/libretime/blob/main/CHANGELOG.md#420-2024-06-22).

View File

@ -79,6 +79,8 @@ indicator.
| Add Autoloading Playlist? | If checked, allows for the following options |
| Select Playlist | Select the playlist the show will autofill from (shows autofill exactly one hour before air). If you wish to use a smartblock you must add it to a playlist and then select that playlist. This can be used to auto schedule new podcast episodes to air. |
| Repeat Playlist Until Show Is Full | If checked, the playlist will be added to the show multiple times until the slot is full. Useful for applying a one-hour music playlist made up of smartblocks to a two-hour show. |
| Select Intro Playlist | Select the playlist to replace the global intro playlist from settings. If you wish to use a smartblock you must add it to a playlist and then select that playlist. |
| Select Outro Playlist | Select the playlist to replace the global outro playlist from settings. If you wish to use a smartblock you must add it to a playlist and then select that playlist. |
| _Live Stream Input_ | |
| Use LibreTime/Custom Authentication | |
| Show Source | |

View File

@ -49,7 +49,7 @@
"css/users.css": "94c94817a8505ff4dfcd090987859a7e",
"css/waveform.css": "4ce429708933e6da1a2f3bdb2a01db52",
"js/airtime/airtime_bootstrap.js": "9575982385f6c74e2b4ec61e30214a7c",
"js/airtime/audiopreview/preview_jplayer.js": "133b4b9a3436716a8367d353f1658da3",
"js/airtime/audiopreview/preview_jplayer.js": "d3402345279a9f4b86b381bae87d6de8",
"js/airtime/buttons/buttons.js": "1a984b1e01262816c899c5fa3f12e3cd",
"js/airtime/common/audioplaytest.js": "93737dabc4cce4fcdcc6d54acf86d16d",
"js/airtime/common/common.js": "8c0675f5a1c8d95323b2f3983c658f62",
@ -59,7 +59,7 @@
"js/airtime/dashboard/versiontooltip.js": "53ed1c2f7dd9527cba80bbcdb239ac88",
"js/airtime/library/events/library_playlistbuilder.js": "7191ee58ad07b8f652be02bb131eb5e6",
"js/airtime/library/events/library_showbuilder.js": "f3d3f65fe1e7a80cd17c228889c6a1ae",
"js/airtime/library/library.js": "bf61a213cf38521d1892034628faf17c",
"js/airtime/library/library.js": "869b3117dc2c119fac61775d78f63fa9",
"js/airtime/library/plupload.js": "0f6be5b133650828b9ffc74e7852dc89",
"js/airtime/library/podcast.js": "4dedd84cb571cdba2401bfb8ba621e69",
"js/airtime/library/publish.js": "ab3a1452dd332cdb0773241a1c17b7e0",
@ -122,7 +122,7 @@
"js/jplayer/skin/jplayer.airtime.audio.preview.css": "c721fe0587569391dcfa7d0f7b440d2b",
"js/jplayer/skin/jplayer.audio-preview.blue.monday.css": "8565bf8e077eeb5bbba3c88bed42a590",
"js/jplayer/skin/jplayer.blue.monday.css": "491c7a82ae4571ae4a73645bf9755eaf",
"js/libs/CSVexport.js": "07a91f824f41d2d0d1884b5dd10f63e4",
"js/libs/CSVexport.js": "42c1fcfff5c717482f21bff1a9002295",
"js/libs/angular.min.js": "26680517e1024ca2c4f9ed4e0aa1619e",
"js/libs/dayjs.min.js": "bea3f1180a3e2e45eccf9d76f990f3b4",
"js/libs/dropzone.min.js": "f59ac59a89d9c569a27ca7ead38d2396",
@ -150,6 +150,7 @@
"js/plupload/i18n/it_IT.js": "d54d63ce65b652322b9411d545223a20",
"js/plupload/i18n/ja_JP.js": "35ffcfa1681e2ffef02fe085ea041436",
"js/plupload/i18n/ko_KR.js": "16f238d8f3bc779345f5e9d16a3471a2",
"js/plupload/i18n/nb_NO.js": "c23d8392d1f570b24a2bfe713e52d8b0",
"js/plupload/i18n/pl_PL.js": "5a32f95c5a79b846d3fc0388469beb40",
"js/plupload/i18n/pt_BR.js": "049e0eade66ed92564e1468051e70167",
"js/plupload/i18n/ru_RU.js": "a4ede8ec9bd8f1d703d55bc135453042",

View File

@ -0,0 +1,148 @@
<?php
/**
* Auth adaptor for basic header authentication.
*/
class LibreTime_Auth_Adaptor_Header implements Zend_Auth_Adapter_Interface
{
/**
* @throws Exception
*/
public function authenticate(): Zend_Auth_Result
{
$trustedIp = Config::get('header_auth.proxy_ip');
if ($trustedIp != null && $_SERVER['REMOTE_ADDR'] != trim($trustedIp)) {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
}
$userHeader = Config::get('header_auth.user_header');
$groupsHeader = Config::get('header_auth.groups_header');
$emailHeader = Config::get('header_auth.email_header');
$nameHeader = Config::get('header_auth.name_header');
$userLogin = $this->getHeaderValueOf($userHeader);
if ($userLogin == null) {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
}
$subj = CcSubjsQuery::create()->findOneByDbLogin($userLogin);
if ($subj == null) {
$user = new Application_Model_User('');
$user->setPassword('');
$user->setLogin($userLogin);
} else {
$user = new Application_Model_User($subj->getDbId());
}
$name = $this->getHeaderValueOf($nameHeader);
$user->setEmail($this->getHeaderValueOf($emailHeader));
$user->setFirstName($this->getFirstName($name) ?? '');
$user->setLastName($this->getLastName($name) ?? '');
$user->setType($this->getUserType($this->getHeaderValueOf($groupsHeader)));
$user->save();
$this->user = $user;
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);
}
private function getUserType(?string $groups): string
{
if ($groups == null) {
return UTYPE_GUEST;
}
$groups = array_map(fn ($group) => trim($group), explode(',', $groups));
$superAdminGroup = Config::get('header_auth.group_map.superadmin');
if (in_array($superAdminGroup, $groups)) {
return UTYPE_SUPERADMIN;
}
$adminGroup = Config::get('header_auth.group_map.admin');
if (in_array($adminGroup, $groups)) {
return UTYPE_ADMIN;
}
$programManagerGroup = Config::get('header_auth.group_map.program_manager');
if (in_array($programManagerGroup, $groups)) {
return UTYPE_PROGRAM_MANAGER;
}
$hostGroup = Config::get('header_auth.group_map.host');
if (in_array($hostGroup, $groups)) {
return UTYPE_HOST;
}
return UTYPE_GUEST;
}
private function getFirstName(?string $name): ?string
{
if ($name == null) {
return null;
}
$result = explode(' ', $name, 2);
return $result[0];
}
private function getLastName(?string $name): ?string
{
if ($name == null) {
return null;
}
$result = explode(' ', $name, 2);
return end($result);
}
private function getHeaderValueOf(string $httpHeader): ?string
{
// Normalize the header name to match server's format
$normalizedHeader = 'HTTP_' . strtoupper(str_replace('-', '_', $httpHeader));
return $_SERVER[$normalizedHeader] ?? null;
}
// Needed for zend auth adapter
private Application_Model_User $user;
public function setIdentity($username)
{
return $this;
}
public function setCredential($password)
{
return $this;
}
/**
* return dummy object for internal auth handling.
*
* we need to build a dummpy object since the auth layer knows nothing about the db
*
* @param null $returnColumns
* @param null $omitColumns
*
* @return stdClass
*/
public function getResultRowObject($returnColumns = null, $omitColumns = null)
{
$o = new stdClass();
$o->id = $this->user->getId();
$o->username = $this->user->getLogin();
$o->password = $this->user->getPassword();
$o->real_name = implode(' ', [$this->user->getFirstName(), $this->user->getLastName()]);
$o->type = $this->user->getType();
$o->login = $this->user->getLogin();
return $o;
}
}

View File

@ -33,8 +33,17 @@ class AutoPlaylistManager
// call the addPlaylist to show function and don't check for user permission to avoid call to non-existant user object
$sid = $si->getShowId();
$playlistrepeat = new Application_Model_Show($sid);
$introplaylistid = Application_Model_Preference::GetIntroPlaylist();
$outroplaylistid = Application_Model_Preference::GetOutroPlaylist();
if ($playlistrepeat->getHasOverrideIntroPlaylist()) {
$introplaylistid = $playlistrepeat->getIntroPlaylistId();
} else {
$introplaylistid = Application_Model_Preference::GetIntroPlaylist();
}
if ($playlistrepeat->getHasOverrideOutroPlaylist()) {
$outroplaylistid = $playlistrepeat->getOutroPlaylistId();
} else {
$outroplaylistid = Application_Model_Preference::GetOutroPlaylist();
}
// we want to check and see if we need to repeat this process until the show is 100% scheduled
// so we create a while loop and break it immediately if repeat until full isn't enabled

View File

@ -98,6 +98,7 @@ class Application_Common_LocaleHelper
'mt' => _('Maltese'),
'my' => _('Burmese'),
'na' => _('Nauru'),
'nb' => _('Norwegian Bokmål'),
'ne' => _('Nepali'),
'nl' => _('Dutch'),
'no' => _('Norwegian'),

View File

@ -99,6 +99,22 @@ class Schema implements ConfigurationInterface
/**/->scalarNode('filter_field')->end()
->end()->end()
// Header Auth Schema
->arrayNode('header_auth')->children()
/**/->scalarNode('user_header')->defaultValue('Remote-User')->end()
/**/->scalarNode('groups_header')->defaultValue('Remote-Groups')->end()
/**/->scalarNode('email_header')->defaultValue('Remote-Email')->end()
/**/->scalarNode('name_header')->defaultValue('Remote-Name')->end()
/**/->scalarNode('proxy_ip')->end()
/**/->scalarNode('locale')->defaultValue('en-US')->end()
/**/->arrayNode('group_map')->children()
/* */->scalarNode('host')->end()
/* */->scalarNode('program_manager')->end()
/* */->scalarNode('admin')->end()
/* */->scalarNode('superadmin')->end()
/**/->end()->end()
->end()->end()
// Playout schema
->arrayNode('playout')
/**/->ignoreExtraKeys()

View File

@ -398,7 +398,6 @@ class LibraryController extends Zend_Controller_Action
$this->view->id = $file_id;
$this->view->title = $file->getPropelOrm()->getDbTrackTitle();
$this->view->artist_name = $file->getPropelOrm()->getDbArtistName();
$this->view->filePath = $file->getPropelOrm()->getDbFilepath();
$this->view->artwork = $file->getPropelOrm()->getDbArtwork();
$this->view->replay_gain = $file->getPropelOrm()->getDbReplayGain();
$this->view->cuein = $file->getPropelOrm()->getDbCuein();
@ -406,6 +405,28 @@ class LibraryController extends Zend_Controller_Action
$this->view->format = $file->getPropelOrm()->getDbFormat();
$this->view->bit_rate = $file->getPropelOrm()->getDbBitRate();
$this->view->sample_rate = $file->getPropelOrm()->getDbSampleRate();
$filePath = $file->getPropelOrm()->getDbFilepath();
if ($isAdmin) {
$this->view->file_name = $filePath;
} else {
$fileParts = explode(DIRECTORY_SEPARATOR, $filePath);
$filename = end($fileParts);
$this->view->file_name = $filename;
}
// 1000 B in KB and 1000 KB in MB and 1000 MB in GB
$size = $file->getPropelOrm()->getFileSize();
if ($size < 1000) {
// Use B up to 1 KB
$this->view->file_size = $size . ' B';
} elseif ($size < (500 * 1000)) {
// Use KB up to 500 KB
$this->view->file_size = round($size / 1000, 1) . ' KB';
} elseif ($size < (1 * 1000 * 1000 * 1000)) {
// Use MB up to 1 GB
$this->view->file_size = round($size / 1000 / 1000, 1) . ' MB';
} else {
$this->view->file_size = round($size / 1000 / 1000 / 1000, 1) . ' GB';
}
$this->view->html = $this->view->render('library/edit-file-md.phtml');
}

View File

@ -44,44 +44,37 @@ class LoginController extends Zend_Controller_Action
$form = new Application_Form_Login();
$message = _('Please enter your username and password.');
$authAdapter = Application_Model_Auth::getAuthAdapter();
if ($request->isPost()) {
// Open the session for writing, because we close it for writing by default in Bootstrap.php as an optimization.
// session_start();
if ($authAdapter instanceof LibreTime_Auth_Adaptor_Header || ($request->isPost() && $form->isValid($request->getPost()))) {
// get the username and password from the form
$username = $form->getValue('username');
$password = $form->getValue('password');
$locale = $form->getValue('locale');
if ($form->isValid($request->getPost())) {
// get the username and password from the form
$username = $form->getValue('username');
$password = $form->getValue('password');
$locale = $form->getValue('locale');
// pass to the adapter the submitted username and password
$authAdapter->setIdentity($username)
->setCredential($password);
$authAdapter = Application_Model_Auth::getAuthAdapter();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
Zend_Session::regenerateId();
// all info about this user from the login table omit only the password
$userInfo = $authAdapter->getResultRowObject(null, 'password');
// pass to the adapter the submitted username and password
$authAdapter->setIdentity($username)
->setCredential($password);
// the default storage is a session with namespace Zend_Auth
$authStorage = $auth->getStorage();
$authStorage->write($userInfo);
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
Zend_Session::regenerateId();
// all info about this user from the login table omit only the password
$userInfo = $authAdapter->getResultRowObject(null, 'password');
Application_Model_LoginAttempts::resetAttempts($_SERVER['REMOTE_ADDR']);
Application_Model_Subjects::resetLoginAttempts($username);
// the default storage is a session with namespace Zend_Auth
$authStorage = $auth->getStorage();
$authStorage->write($userInfo);
// set the user locale in case user changed it in when logging in
Application_Model_Preference::SetUserLocale($locale);
Application_Model_LoginAttempts::resetAttempts($_SERVER['REMOTE_ADDR']);
Application_Model_Subjects::resetLoginAttempts($username);
// set the user locale in case user changed it in when logging in
Application_Model_Preference::SetUserLocale($locale);
$this->_redirect('showbuilder');
} else {
$form = $this->loginError($username);
}
$this->_redirect('showbuilder');
} else {
$form = $this->loginError($username);
}
}

View File

@ -13,6 +13,8 @@ class Application_Form_AddShowAutoPlaylist extends Zend_Form_SubForm
// and store to assoc array
$maxLens = Application_Model_Show::getMaxLengths();
$playlistNames = Application_Model_Library::getPlaylistNames(true);
// Add autoplaylist checkbox element
$this->addElement('checkbox', 'add_show_has_autoplaylist', [
'label' => _('Add Autoloading Playlist ?'),
@ -23,10 +25,11 @@ class Application_Form_AddShowAutoPlaylist extends Zend_Form_SubForm
$autoPlaylistSelect = new Zend_Form_Element_Select('add_show_autoplaylist_id');
$autoPlaylistSelect->setLabel(_('Select Playlist'));
$autoPlaylistSelect->setMultiOptions(Application_Model_Library::getPlaylistNames(true));
$autoPlaylistSelect->setMultiOptions($playlistNames);
$autoPlaylistSelect->setValue(null);
$autoPlaylistSelect->setDecorators(['ViewHelper']);
$this->addElement($autoPlaylistSelect);
// Add autoplaylist checkbox element
$this->addElement('checkbox', 'add_show_autoplaylist_repeat', [
'label' => _('Repeat Playlist Until Show is Full ?'),
@ -34,6 +37,23 @@ class Application_Form_AddShowAutoPlaylist extends Zend_Form_SubForm
'class' => 'input_text',
'decorators' => ['ViewHelper'],
]);
// Append 'Default' to 'None' option
$playlistNames[null] = _('None') . '/' . _('Default');
$introPlaylistSelect = new Zend_Form_Element_Select('add_show_intro_playlist_id');
$introPlaylistSelect->setLabel(_('Select Intro Playlist'));
$introPlaylistSelect->setMultiOptions($playlistNames);
$introPlaylistSelect->setValue(null);
$introPlaylistSelect->setDecorators(['ViewHelper']);
$this->addElement($introPlaylistSelect);
$outroPlaylistSelect = new Zend_Form_Element_Select('add_show_outro_playlist_id');
$outroPlaylistSelect->setLabel(_('Select Outro Playlist'));
$outroPlaylistSelect->setMultiOptions($playlistNames);
$outroPlaylistSelect->setValue(null);
$outroPlaylistSelect->setDecorators(['ViewHelper']);
$this->addElement($outroPlaylistSelect);
}
public function disable()

View File

@ -105,16 +105,18 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
$tracktypeDefault->setValue(Application_Model_Preference::GetTrackTypeDefault());
$this->addElement($tracktypeDefault);
$playlistNames = Application_Model_Library::getPlaylistNames(true);
// add intro playlist select here
$introPlaylistSelect = new Zend_Form_Element_Select('introPlaylistSelect');
$introPlaylistSelect->setLabel(_('Intro Autoloading Playlist'));
$introPlaylistSelect->setMultiOptions(Application_Model_Library::getPlaylistNames(true));
$introPlaylistSelect->setMultiOptions($playlistNames);
$introPlaylistSelect->setValue(Application_Model_Preference::GetIntroPlaylist());
$this->addElement($introPlaylistSelect);
$outroPlaylistSelect = new Zend_Form_Element_Select('outroPlaylistSelect');
$outroPlaylistSelect->setLabel(_('Outro Autoloading Playlist'));
$outroPlaylistSelect->setMultiOptions(Application_Model_Library::getPlaylistNames(true));
$outroPlaylistSelect->setMultiOptions($playlistNames);
$outroPlaylistSelect->setValue(Application_Model_Preference::GetOutroPlaylist());
$this->addElement($outroPlaylistSelect);

View File

@ -1300,89 +1300,87 @@ SQL;
$info = $this->getListofFilesMeetCriteria($show);
$files = $info['files'];
$limit = $info['limit'];
$repeat = $info['repeat_tracks'];
$overflow = $info['overflow_tracks'];
$insertList = [];
$totalTime = 0;
$totalItems = 0;
$repeat = $info['repeat_tracks'] == 1;
$overflow = $info['overflow_tracks'] == 1;
$isRandomSort = $info['sort_type'] == 'random';
$blockTime = $limit['time'];
$blockItems = $limit['items'];
if ($files->isEmpty()) {
return $insertList;
return [];
}
// this moves the pointer to the first element in the collection
$files->getFirst();
$iterator = $files->getIterator();
$isBlockFull = false;
while ($iterator->valid()) {
/**
* @var Track[] $tracks
*/
$tracks = [];
$maxItems = 500;
while ($iterator->valid() && count($tracks) < $maxItems) {
$id = $iterator->current()->getDbId();
$fileLength = $iterator->current()->getCueLength();
$length = Application_Common_DateHelper::calculateLengthInSeconds($fileLength);
// if the block is setup to allow the overflow of tracks this will add the next track even if it becomes
// longer than the time limit
if ($overflow == 1) {
$insertList[] = ['id' => $id, 'length' => $length];
$totalTime += $length;
++$totalItems;
}
// otherwise we need to check to determine if the track will make the playlist exceed the totalTime before
// adding it this could loop through a lot of tracks so I used the totalItems limit to prevent
// the algorithm from parsing too many items.
else {
$projectedTime = $totalTime + $length;
if ($projectedTime > $limit['time']) {
++$totalItems;
} else {
$insertList[] = ['id' => $id, 'length' => $length];
$totalTime += $length;
++$totalItems;
}
}
if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) {
$isBlockFull = true;
break;
}
$tracks[] = new Track($id, $length);
$iterator->next();
}
$sizeOfInsert = count($insertList);
/**
* @var Track[] $insertList
*/
$insertList = [];
$totalTime = 0;
if ($isRandomSort && !$overflow && $blockItems === null) {
$minTrackLength = min(array_map(fn (Track $item) => $item->length, $tracks));
do {
$solution = SSPSolution::solve($tracks, $blockTime - $totalTime);
$insertList = array_merge($insertList, $solution->tracks);
$totalTime += $solution->sum;
} while ($repeat && ($blockTime - $totalTime) > $minTrackLength);
shuffle($insertList);
} else {
$isFull = function () use (&$blockItems, &$insertList, &$totalTime, &$blockTime) {
return $blockItems !== null && count($insertList) >= $blockItems || $totalTime > $blockTime;
};
// if block is not full and repeat_track is check, fill up more
// additionally still don't overflow the limit
while (!$isBlockFull && $repeat == 1 && $sizeOfInsert > 0) {
Logging::debug('adding repeated tracks.');
Logging::debug('total time = ' . $totalTime);
$randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert));
// this will also allow the overflow of tracks so that time limited smart blocks will schedule until they
// are longer than the time limit rather than never scheduling past the time limit
if ($overflow == 1) {
$insertList[] = $insertList[$randomEleKey];
$totalTime += $insertList[$randomEleKey]['length'];
++$totalItems;
} else {
$projectedTime = $totalTime + $insertList[$randomEleKey]['length'];
if ($projectedTime > $limit['time']) {
++$totalItems;
$addTrack = function (Track $track) use ($overflow, $blockTime, &$insertList, &$totalTime) {
if ($overflow) {
$insertList[] = $track;
$totalTime += $track->length;
} else {
$insertList[] = $insertList[$randomEleKey];
$totalTime += $insertList[$randomEleKey]['length'];
++$totalItems;
$projectedTime = $totalTime + $track->length;
if ($projectedTime <= $blockTime) {
$insertList[] = $track;
$totalTime += $track->length;
}
}
};
foreach ($tracks as $track) {
$addTrack($track);
if ($isFull()) {
break;
}
}
if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) {
break;
$sizeOfInsert = count($insertList);
while (!$isFull() && $repeat && $sizeOfInsert > 0) {
Logging::debug('adding repeated tracks.');
Logging::debug('total time = ' . $totalTime);
$track = $insertList[array_rand(array_slice($insertList, 0, $sizeOfInsert))];
$addTrack($track);
}
}
return $insertList;
return array_map(fn (Track $track) => ['id' => $track->id, 'length' => $track->length], $insertList);
}
/**
@ -1564,24 +1562,24 @@ SQL;
$spCriteriaValue = $this->resolveDate($spCriteriaValue);
if ($spCriteriaModifier == 'starts with') {
if ($spCriteriaModifier == CriteriaModifier::STARTS_WITH) {
$spCriteriaValue = "{$spCriteriaValue}%";
} elseif ($spCriteriaModifier == 'ends with') {
} elseif ($spCriteriaModifier == CriteriaModifier::ENDS_WITH) {
$spCriteriaValue = "%{$spCriteriaValue}";
} elseif ($spCriteriaModifier == 'contains' || $spCriteriaModifier == 'does not contain') {
} elseif ($spCriteriaModifier == CriteriaModifier::CONTAINS || $spCriteriaModifier == CriteriaModifier::DOES_NOT_CONTAIN) {
$spCriteriaValue = "%{$spCriteriaValue}%";
} elseif ($spCriteriaModifier == 'is in the range') {
} elseif ($spCriteriaModifier == CriteriaModifier::IS_IN_THE_RANGE) {
$spCriteriaValue = "{$spCriteria} >= '{$spCriteriaValue}' AND {$spCriteria} <= '{$spCriteriaExtra}'";
} elseif ($spCriteriaModifier == 'before') {
} elseif ($spCriteriaModifier == CriteriaModifier::BEFORE) {
// need to pull in the current time and subtract the value or figure out how to make it relative
$relativedate = new DateTime($spCriteriaValue);
$dt = $relativedate->format(DateTime::ISO8601);
$spCriteriaValue = "COALESCE({$spCriteria}, DATE '-infinity') <= '{$dt}'";
} elseif ($spCriteriaModifier == 'after') {
} elseif ($spCriteriaModifier == CriteriaModifier::AFTER) {
$relativedate = new DateTime($spCriteriaValue);
$dt = $relativedate->format(DateTime::ISO8601);
$spCriteriaValue = "COALESCE({$spCriteria}, DATE '-infinity') >= '{$dt}'";
} elseif ($spCriteriaModifier == 'between') {
} elseif ($spCriteriaModifier == CriteriaModifier::BETWEEN) {
$fromrelativedate = new DateTime($spCriteriaValue);
$fdt = $fromrelativedate->format(DateTime::ISO8601);
@ -1596,6 +1594,11 @@ SQL;
if ($spCriteria == 'owner_id') {
$spCriteria = 'subj.login';
}
if ($spCriteria == 'filepath') {
$spCriteria = "reverse(split_part(reverse(filepath), '/', 1))";
}
if ($i > 0 && $prevgroup == $group) {
$qry->addOr($spCriteria, $spCriteriaValue, $spCriteriaModifier);
} else {
@ -1628,12 +1631,10 @@ SQL;
$qry->addDescendingOrderByColumn('utime');
} elseif ($sortTracks == 'oldest') {
$qry->addAscendingOrderByColumn('utime');
}
// these sort additions are needed to override the default postgres NULL sort behavior
elseif ($sortTracks == 'mostrecentplay') {
$qry->addDescendingOrderByColumn('(lptime IS NULL), lptime');
} elseif ($sortTracks == 'mostrecentplay') {
$qry->addAscendingOrderByColumn('lptime DESC NULLS LAST, filepath');
} elseif ($sortTracks == 'leastrecentplay') {
$qry->addAscendingOrderByColumn('(lptime IS NOT NULL), lptime');
$qry->addAscendingOrderByColumn('lptime ASC NULLS FIRST, filepath');
} elseif ($sortTracks == 'random') {
$qry->addAscendingOrderByColumn('random()');
} else {
@ -1677,7 +1678,7 @@ SQL;
try {
$out = $qry->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)->find();
return ['files' => $out, 'limit' => $limits, 'repeat_tracks' => $repeatTracks, 'overflow_tracks' => $overflowTracks, 'count' => $out->count()];
return ['files' => $out, 'limit' => $limits, 'repeat_tracks' => $repeatTracks, 'overflow_tracks' => $overflowTracks, 'count' => $out->count(), 'sort_type' => $sortTracks];
} catch (Exception $e) {
Logging::info($e);
}
@ -1745,6 +1746,140 @@ SQL;
// smart block functions end
}
class Track
{
public int $id;
public float $length;
public function __construct($id, $length)
{
$this->id = $id;
$this->length = $length;
}
public function __toString(): string
{
return (string) $this->id;
}
}
/**
* Using a randomized greedy with local improvement approximation solution for the Subset Sum Problem.
*
* https://web.stevens.edu/algebraic/Files/SubsetSum/przydatek99fast.pdf
*/
class SSPSolution
{
/**
* @var Track[]
*/
public array $tracks;
public float $sum = 0.0;
public function __construct($tracks = [], $sum = null)
{
$this->tracks = $tracks;
if ($sum !== null) {
$this->sum = $sum;
} else {
foreach ($this->tracks as $track) {
$this->sum += $track->length;
}
}
}
public function add(Track $track): SSPSolution
{
$new = $this->tracks;
$new[] = $track;
return new SSPSolution($new, $this->sum + $track->length);
}
public function replace(Track $old, Track $new): SSPSolution
{
return new SSPSolution(array_map(fn (Track $it) => $it === $old ? $new : $it, $this->tracks));
}
public static function isCloseEnough(float $delta): bool
{
return $delta < 0.25;
}
public static function maxByOrNull(array $array, callable $callback)
{
$max = null;
$v = null;
foreach ($array as $item) {
$value = $callback($item);
if ($max === null || $v < $value) {
$max = $item;
$v = $value;
}
}
return $max;
}
/**
* @param Track[] $tracks
*/
public static function solve(array $tracks, float $target, int $trials = 50): SSPSolution
{
$best = new SSPSolution();
for ($trial = 0; $trial < $trials; ++$trial) {
shuffle($tracks);
$initial = array_reduce($tracks, function (SSPSolution $solution, Track $track) use ($target) {
$new = $solution->add($track);
if ($new->sum <= $target) {
return $new;
}
return $solution;
}, new SSPSolution());
if (count($initial->tracks) == count($tracks)) {
return $initial;
}
$acceptedItems = $initial->tracks;
shuffle($acceptedItems);
$localImprovement = array_reduce($acceptedItems, function (SSPSolution $solution, Track $track) use ($target, $tracks) {
$delta = $target - $solution->sum;
if (self::isCloseEnough($delta)) {
return $solution;
}
$replacement = self::maxByOrNull(
array_filter(
array_diff($tracks, $solution->tracks),
fn (Track $it) => $it->length > $track->length && $it->length - $track->length <= $delta,
),
fn (Track $it) => $it->length,
);
if ($replacement === null) {
return $solution;
}
return $solution->replace($track, $replacement);
}, $initial);
if ($localImprovement->sum > $best->sum) {
$best = $localImprovement;
}
if ($best->sum === 0.0) {
return $best;
}
}
return $best;
}
}
class BlockNotFoundException extends Exception {}
class BlockNoPermissionException extends Exception {}
class BlockOutDatedException extends Exception {}

View File

@ -19,6 +19,7 @@ final class Application_Model_Locale
'it_IT' => 'Italiano',
'ja_JP' => '日本語',
'ko_KR' => '한국어',
'nb_NO' => 'Norwegian Bokmål (Norway)',
// 'nl_NL' => '',
'pl_PL' => 'Polski',
'pt_BR' => 'Português (Brasil)',

View File

@ -169,6 +169,58 @@ class Application_Model_Show
$show->setDbAutoPlaylistId($playlistid);
}
public function getHasOverrideIntroPlaylist()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbOverrideIntroPlaylist();
}
public function getIntroPlaylistId()
{
$show = CcShowQuery::create()->findPK($this->_showId);
if ($show->getDbOverrideIntroPlaylist()) {
return $show->getDbIntroPlaylistId();
}
return 0;
}
public function setIntroPlaylistId($playlistid)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbOverrideIntroPlaylist($playlistid != 0);
$show->setDbIntroPlaylistId($playlistid);
}
public function getHasOverrideOutroPlaylist()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbOverrideOutroPlaylist();
}
public function getOutroPlaylistId()
{
$show = CcShowQuery::create()->findPK($this->_showId);
if ($show->getDbOverrideOutroPlaylist()) {
return $show->getDbOutroPlaylistId();
}
return 0;
}
public function setOutroPlaylistId($playlistid)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbOverrideOutroPlaylist($playlistid != 0);
$show->setDbOutroPlaylistId($playlistid);
}
public function getHosts()
{
$sql = <<<'SQL'

View File

@ -750,7 +750,7 @@ SQL;
} elseif ($key === 'filepath') {
$plSelect[] = 'NULL::VARCHAR AS ' . $key;
$blSelect[] = 'NULL::VARCHAR AS ' . $key;
$fileSelect[] = $key;
$fileSelect[] = "reverse(split_part(reverse({$key}), '/', 1)) as {$key}";
$streamSelect[] = 'url AS ' . $key;
} elseif ($key == 'mime') {
$plSelect[] = 'NULL::VARCHAR AS ' . $key;

View File

@ -327,6 +327,10 @@ class CcShow extends BaseCcShow
$info['has_autoplaylist'] = $this->getDbHasAutoPlaylist();
$info['autoplaylist_id'] = $this->getDbAutoPlaylistId();
$info['autoplaylist_repeat'] = $this->getDbAutoPlaylistRepeat();
$info['override_intro_playlist'] = $this->getDbOverrideIntroPlaylist();
$info['intro_playlist_id'] = $this->getDbIntroPlaylistId();
$info['override_outro_playlist'] = $this->getDbOverrideOutroPlaylist();
$info['outro_playlist_id'] = $this->getDbOutroPlaylistId();
return $info;
}

View File

@ -55,7 +55,9 @@ class CcPlaylistTableMap extends TableMap
public function buildRelations()
{
$this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('creator_id' => 'id', ), 'CASCADE', null);
$this->addRelation('CcShow', 'CcShow', RelationMap::ONE_TO_MANY, array('id' => 'autoplaylist_id', ), 'SET NULL', null, 'CcShows');
$this->addRelation('CcShowRelatedByDbAutoPlaylistId', 'CcShow', RelationMap::ONE_TO_MANY, array('id' => 'autoplaylist_id', ), 'SET NULL', null, 'CcShowsRelatedByDbAutoPlaylistId');
$this->addRelation('CcShowRelatedByDbIntroPlaylistId', 'CcShow', RelationMap::ONE_TO_MANY, array('id' => 'intro_playlist_id', ), 'SET NULL', null, 'CcShowsRelatedByDbIntroPlaylistId');
$this->addRelation('CcShowRelatedByDbOutroPlaylistId', 'CcShow', RelationMap::ONE_TO_MANY, array('id' => 'outro_playlist_id', ), 'SET NULL', null, 'CcShowsRelatedByDbOutroPlaylistId');
$this->addRelation('CcPlaylistcontents', 'CcPlaylistcontents', RelationMap::ONE_TO_MANY, array('id' => 'playlist_id', ), 'CASCADE', null, 'CcPlaylistcontentss');
} // buildRelations()

View File

@ -56,6 +56,10 @@ class CcShowTableMap extends TableMap
$this->addColumn('has_autoplaylist', 'DbHasAutoPlaylist', 'BOOLEAN', true, null, false);
$this->addForeignKey('autoplaylist_id', 'DbAutoPlaylistId', 'INTEGER', 'cc_playlist', 'id', false, null, null);
$this->addColumn('autoplaylist_repeat', 'DbAutoPlaylistRepeat', 'BOOLEAN', true, null, false);
$this->addColumn('override_intro_playlist', 'DbOverrideIntroPlaylist', 'BOOLEAN', true, null, false);
$this->addForeignKey('intro_playlist_id', 'DbIntroPlaylistId', 'INTEGER', 'cc_playlist', 'id', false, null, null);
$this->addColumn('override_outro_playlist', 'DbOverrideOutroPlaylist', 'BOOLEAN', true, null, false);
$this->addForeignKey('outro_playlist_id', 'DbOutroPlaylistId', 'INTEGER', 'cc_playlist', 'id', false, null, null);
// validators
} // initialize()
@ -64,7 +68,9 @@ class CcShowTableMap extends TableMap
*/
public function buildRelations()
{
$this->addRelation('CcPlaylist', 'CcPlaylist', RelationMap::MANY_TO_ONE, array('autoplaylist_id' => 'id', ), 'SET NULL', null);
$this->addRelation('CcPlaylistRelatedByDbAutoPlaylistId', 'CcPlaylist', RelationMap::MANY_TO_ONE, array('autoplaylist_id' => 'id', ), 'SET NULL', null);
$this->addRelation('CcPlaylistRelatedByDbIntroPlaylistId', 'CcPlaylist', RelationMap::MANY_TO_ONE, array('intro_playlist_id' => 'id', ), 'SET NULL', null);
$this->addRelation('CcPlaylistRelatedByDbOutroPlaylistId', 'CcPlaylist', RelationMap::MANY_TO_ONE, array('outro_playlist_id' => 'id', ), 'SET NULL', null);
$this->addRelation('CcShowInstances', 'CcShowInstances', RelationMap::ONE_TO_MANY, array('id' => 'show_id', ), 'CASCADE', null, 'CcShowInstancess');
$this->addRelation('CcShowDays', 'CcShowDays', RelationMap::ONE_TO_MANY, array('id' => 'show_id', ), 'CASCADE', null, 'CcShowDayss');
$this->addRelation('CcShowRebroadcast', 'CcShowRebroadcast', RelationMap::ONE_TO_MANY, array('id' => 'show_id', ), 'CASCADE', null, 'CcShowRebroadcasts');

View File

@ -81,8 +81,20 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
/**
* @var PropelObjectCollection|CcShow[] Collection to store aggregation of CcShow objects.
*/
protected $collCcShows;
protected $collCcShowsPartial;
protected $collCcShowsRelatedByDbAutoPlaylistId;
protected $collCcShowsRelatedByDbAutoPlaylistIdPartial;
/**
* @var PropelObjectCollection|CcShow[] Collection to store aggregation of CcShow objects.
*/
protected $collCcShowsRelatedByDbIntroPlaylistId;
protected $collCcShowsRelatedByDbIntroPlaylistIdPartial;
/**
* @var PropelObjectCollection|CcShow[] Collection to store aggregation of CcShow objects.
*/
protected $collCcShowsRelatedByDbOutroPlaylistId;
protected $collCcShowsRelatedByDbOutroPlaylistIdPartial;
/**
* @var PropelObjectCollection|CcPlaylistcontents[] Collection to store aggregation of CcPlaylistcontents objects.
@ -114,7 +126,19 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
* An array of objects scheduled for deletion.
* @var PropelObjectCollection
*/
protected $ccShowsScheduledForDeletion = null;
protected $ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion = null;
/**
* An array of objects scheduled for deletion.
* @var PropelObjectCollection
*/
protected $ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion = null;
/**
* An array of objects scheduled for deletion.
* @var PropelObjectCollection
*/
protected $ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion = null;
/**
* An array of objects scheduled for deletion.
@ -546,7 +570,11 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
if ($deep) { // also de-associate any related objects?
$this->aCcSubjs = null;
$this->collCcShows = null;
$this->collCcShowsRelatedByDbAutoPlaylistId = null;
$this->collCcShowsRelatedByDbIntroPlaylistId = null;
$this->collCcShowsRelatedByDbOutroPlaylistId = null;
$this->collCcPlaylistcontentss = null;
@ -694,18 +722,54 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
$this->resetModified();
}
if ($this->ccShowsScheduledForDeletion !== null) {
if (!$this->ccShowsScheduledForDeletion->isEmpty()) {
foreach ($this->ccShowsScheduledForDeletion as $ccShow) {
if ($this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion !== null) {
if (!$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion->isEmpty()) {
foreach ($this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion as $ccShowRelatedByDbAutoPlaylistId) {
// need to save related object because we set the relation to null
$ccShow->save($con);
$ccShowRelatedByDbAutoPlaylistId->save($con);
}
$this->ccShowsScheduledForDeletion = null;
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion = null;
}
}
if ($this->collCcShows !== null) {
foreach ($this->collCcShows as $referrerFK) {
if ($this->collCcShowsRelatedByDbAutoPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbAutoPlaylistId as $referrerFK) {
if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
$affectedRows += $referrerFK->save($con);
}
}
}
if ($this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion !== null) {
if (!$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion->isEmpty()) {
foreach ($this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion as $ccShowRelatedByDbIntroPlaylistId) {
// need to save related object because we set the relation to null
$ccShowRelatedByDbIntroPlaylistId->save($con);
}
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion = null;
}
}
if ($this->collCcShowsRelatedByDbIntroPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbIntroPlaylistId as $referrerFK) {
if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
$affectedRows += $referrerFK->save($con);
}
}
}
if ($this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion !== null) {
if (!$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion->isEmpty()) {
foreach ($this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion as $ccShowRelatedByDbOutroPlaylistId) {
// need to save related object because we set the relation to null
$ccShowRelatedByDbOutroPlaylistId->save($con);
}
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion = null;
}
}
if ($this->collCcShowsRelatedByDbOutroPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbOutroPlaylistId as $referrerFK) {
if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
$affectedRows += $referrerFK->save($con);
}
@ -922,8 +986,24 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
}
if ($this->collCcShows !== null) {
foreach ($this->collCcShows as $referrerFK) {
if ($this->collCcShowsRelatedByDbAutoPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbAutoPlaylistId as $referrerFK) {
if (!$referrerFK->validate($columns)) {
$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
}
}
}
if ($this->collCcShowsRelatedByDbIntroPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbIntroPlaylistId as $referrerFK) {
if (!$referrerFK->validate($columns)) {
$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
}
}
}
if ($this->collCcShowsRelatedByDbOutroPlaylistId !== null) {
foreach ($this->collCcShowsRelatedByDbOutroPlaylistId as $referrerFK) {
if (!$referrerFK->validate($columns)) {
$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
}
@ -1040,8 +1120,14 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
if (null !== $this->aCcSubjs) {
$result['CcSubjs'] = $this->aCcSubjs->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
}
if (null !== $this->collCcShows) {
$result['CcShows'] = $this->collCcShows->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
if (null !== $this->collCcShowsRelatedByDbAutoPlaylistId) {
$result['CcShowsRelatedByDbAutoPlaylistId'] = $this->collCcShowsRelatedByDbAutoPlaylistId->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
}
if (null !== $this->collCcShowsRelatedByDbIntroPlaylistId) {
$result['CcShowsRelatedByDbIntroPlaylistId'] = $this->collCcShowsRelatedByDbIntroPlaylistId->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
}
if (null !== $this->collCcShowsRelatedByDbOutroPlaylistId) {
$result['CcShowsRelatedByDbOutroPlaylistId'] = $this->collCcShowsRelatedByDbOutroPlaylistId->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
}
if (null !== $this->collCcPlaylistcontentss) {
$result['CcPlaylistcontentss'] = $this->collCcPlaylistcontentss->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
@ -1227,9 +1313,21 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
// store object hash to prevent cycle
$this->startCopy = true;
foreach ($this->getCcShows() as $relObj) {
foreach ($this->getCcShowsRelatedByDbAutoPlaylistId() as $relObj) {
if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves
$copyObj->addCcShow($relObj->copy($deepCopy));
$copyObj->addCcShowRelatedByDbAutoPlaylistId($relObj->copy($deepCopy));
}
}
foreach ($this->getCcShowsRelatedByDbIntroPlaylistId() as $relObj) {
if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves
$copyObj->addCcShowRelatedByDbIntroPlaylistId($relObj->copy($deepCopy));
}
}
foreach ($this->getCcShowsRelatedByDbOutroPlaylistId() as $relObj) {
if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves
$copyObj->addCcShowRelatedByDbOutroPlaylistId($relObj->copy($deepCopy));
}
}
@ -1352,8 +1450,14 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
*/
public function initRelation($relationName)
{
if ('CcShow' == $relationName) {
$this->initCcShows();
if ('CcShowRelatedByDbAutoPlaylistId' == $relationName) {
$this->initCcShowsRelatedByDbAutoPlaylistId();
}
if ('CcShowRelatedByDbIntroPlaylistId' == $relationName) {
$this->initCcShowsRelatedByDbIntroPlaylistId();
}
if ('CcShowRelatedByDbOutroPlaylistId' == $relationName) {
$this->initCcShowsRelatedByDbOutroPlaylistId();
}
if ('CcPlaylistcontents' == $relationName) {
$this->initCcPlaylistcontentss();
@ -1361,36 +1465,36 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
}
/**
* Clears out the collCcShows collection
* Clears out the collCcShowsRelatedByDbAutoPlaylistId collection
*
* This does not modify the database; however, it will remove any associated objects, causing
* them to be refetched by subsequent calls to accessor method.
*
* @return CcPlaylist The current object (for fluent API support)
* @see addCcShows()
* @see addCcShowsRelatedByDbAutoPlaylistId()
*/
public function clearCcShows()
public function clearCcShowsRelatedByDbAutoPlaylistId()
{
$this->collCcShows = null; // important to set this to null since that means it is uninitialized
$this->collCcShowsPartial = null;
$this->collCcShowsRelatedByDbAutoPlaylistId = null; // important to set this to null since that means it is uninitialized
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = null;
return $this;
}
/**
* reset is the collCcShows collection loaded partially
* reset is the collCcShowsRelatedByDbAutoPlaylistId collection loaded partially
*
* @return void
*/
public function resetPartialCcShows($v = true)
public function resetPartialCcShowsRelatedByDbAutoPlaylistId($v = true)
{
$this->collCcShowsPartial = $v;
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = $v;
}
/**
* Initializes the collCcShows collection.
* Initializes the collCcShowsRelatedByDbAutoPlaylistId collection.
*
* By default this just sets the collCcShows collection to an empty array (like clearcollCcShows());
* By default this just sets the collCcShowsRelatedByDbAutoPlaylistId collection to an empty array (like clearcollCcShowsRelatedByDbAutoPlaylistId());
* however, you may wish to override this method in your stub class to provide setting appropriate
* to your application -- for example, setting the initial array to the values stored in database.
*
@ -1399,13 +1503,13 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
*
* @return void
*/
public function initCcShows($overrideExisting = true)
public function initCcShowsRelatedByDbAutoPlaylistId($overrideExisting = true)
{
if (null !== $this->collCcShows && !$overrideExisting) {
if (null !== $this->collCcShowsRelatedByDbAutoPlaylistId && !$overrideExisting) {
return;
}
$this->collCcShows = new PropelObjectCollection();
$this->collCcShows->setModel('CcShow');
$this->collCcShowsRelatedByDbAutoPlaylistId = new PropelObjectCollection();
$this->collCcShowsRelatedByDbAutoPlaylistId->setModel('CcShow');
}
/**
@ -1422,79 +1526,79 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
* @return PropelObjectCollection|CcShow[] List of CcShow objects
* @throws PropelException
*/
public function getCcShows($criteria = null, PropelPDO $con = null)
public function getCcShowsRelatedByDbAutoPlaylistId($criteria = null, PropelPDO $con = null)
{
$partial = $this->collCcShowsPartial && !$this->isNew();
if (null === $this->collCcShows || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShows) {
$partial = $this->collCcShowsRelatedByDbAutoPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbAutoPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbAutoPlaylistId) {
// return empty collection
$this->initCcShows();
$this->initCcShowsRelatedByDbAutoPlaylistId();
} else {
$collCcShows = CcShowQuery::create(null, $criteria)
->filterByCcPlaylist($this)
$collCcShowsRelatedByDbAutoPlaylistId = CcShowQuery::create(null, $criteria)
->filterByCcPlaylistRelatedByDbAutoPlaylistId($this)
->find($con);
if (null !== $criteria) {
if (false !== $this->collCcShowsPartial && count($collCcShows)) {
$this->initCcShows(false);
if (false !== $this->collCcShowsRelatedByDbAutoPlaylistIdPartial && count($collCcShowsRelatedByDbAutoPlaylistId)) {
$this->initCcShowsRelatedByDbAutoPlaylistId(false);
foreach ($collCcShows as $obj) {
if (false == $this->collCcShows->contains($obj)) {
$this->collCcShows->append($obj);
foreach ($collCcShowsRelatedByDbAutoPlaylistId as $obj) {
if (false == $this->collCcShowsRelatedByDbAutoPlaylistId->contains($obj)) {
$this->collCcShowsRelatedByDbAutoPlaylistId->append($obj);
}
}
$this->collCcShowsPartial = true;
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = true;
}
$collCcShows->getInternalIterator()->rewind();
$collCcShowsRelatedByDbAutoPlaylistId->getInternalIterator()->rewind();
return $collCcShows;
return $collCcShowsRelatedByDbAutoPlaylistId;
}
if ($partial && $this->collCcShows) {
foreach ($this->collCcShows as $obj) {
if ($partial && $this->collCcShowsRelatedByDbAutoPlaylistId) {
foreach ($this->collCcShowsRelatedByDbAutoPlaylistId as $obj) {
if ($obj->isNew()) {
$collCcShows[] = $obj;
$collCcShowsRelatedByDbAutoPlaylistId[] = $obj;
}
}
}
$this->collCcShows = $collCcShows;
$this->collCcShowsPartial = false;
$this->collCcShowsRelatedByDbAutoPlaylistId = $collCcShowsRelatedByDbAutoPlaylistId;
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = false;
}
}
return $this->collCcShows;
return $this->collCcShowsRelatedByDbAutoPlaylistId;
}
/**
* Sets a collection of CcShow objects related by a one-to-many relationship
* Sets a collection of CcShowRelatedByDbAutoPlaylistId objects related by a one-to-many relationship
* to the current object.
* It will also schedule objects for deletion based on a diff between old objects (aka persisted)
* and new objects from the given Propel collection.
*
* @param PropelCollection $ccShows A Propel collection.
* @param PropelCollection $ccShowsRelatedByDbAutoPlaylistId A Propel collection.
* @param PropelPDO $con Optional connection object
* @return CcPlaylist The current object (for fluent API support)
*/
public function setCcShows(PropelCollection $ccShows, PropelPDO $con = null)
public function setCcShowsRelatedByDbAutoPlaylistId(PropelCollection $ccShowsRelatedByDbAutoPlaylistId, PropelPDO $con = null)
{
$ccShowsToDelete = $this->getCcShows(new Criteria(), $con)->diff($ccShows);
$ccShowsRelatedByDbAutoPlaylistIdToDelete = $this->getCcShowsRelatedByDbAutoPlaylistId(new Criteria(), $con)->diff($ccShowsRelatedByDbAutoPlaylistId);
$this->ccShowsScheduledForDeletion = $ccShowsToDelete;
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion = $ccShowsRelatedByDbAutoPlaylistIdToDelete;
foreach ($ccShowsToDelete as $ccShowRemoved) {
$ccShowRemoved->setCcPlaylist(null);
foreach ($ccShowsRelatedByDbAutoPlaylistIdToDelete as $ccShowRelatedByDbAutoPlaylistIdRemoved) {
$ccShowRelatedByDbAutoPlaylistIdRemoved->setCcPlaylistRelatedByDbAutoPlaylistId(null);
}
$this->collCcShows = null;
foreach ($ccShows as $ccShow) {
$this->addCcShow($ccShow);
$this->collCcShowsRelatedByDbAutoPlaylistId = null;
foreach ($ccShowsRelatedByDbAutoPlaylistId as $ccShowRelatedByDbAutoPlaylistId) {
$this->addCcShowRelatedByDbAutoPlaylistId($ccShowRelatedByDbAutoPlaylistId);
}
$this->collCcShows = $ccShows;
$this->collCcShowsPartial = false;
$this->collCcShowsRelatedByDbAutoPlaylistId = $ccShowsRelatedByDbAutoPlaylistId;
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = false;
return $this;
}
@ -1508,16 +1612,16 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
* @return int Count of related CcShow objects.
* @throws PropelException
*/
public function countCcShows(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
public function countCcShowsRelatedByDbAutoPlaylistId(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
{
$partial = $this->collCcShowsPartial && !$this->isNew();
if (null === $this->collCcShows || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShows) {
$partial = $this->collCcShowsRelatedByDbAutoPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbAutoPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbAutoPlaylistId) {
return 0;
}
if ($partial && !$criteria) {
return count($this->getCcShows());
return count($this->getCcShowsRelatedByDbAutoPlaylistId());
}
$query = CcShowQuery::create(null, $criteria);
if ($distinct) {
@ -1525,11 +1629,11 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
}
return $query
->filterByCcPlaylist($this)
->filterByCcPlaylistRelatedByDbAutoPlaylistId($this)
->count($con);
}
return count($this->collCcShows);
return count($this->collCcShowsRelatedByDbAutoPlaylistId);
}
/**
@ -1539,18 +1643,18 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
* @param CcShow $l CcShow
* @return CcPlaylist The current object (for fluent API support)
*/
public function addCcShow(CcShow $l)
public function addCcShowRelatedByDbAutoPlaylistId(CcShow $l)
{
if ($this->collCcShows === null) {
$this->initCcShows();
$this->collCcShowsPartial = true;
if ($this->collCcShowsRelatedByDbAutoPlaylistId === null) {
$this->initCcShowsRelatedByDbAutoPlaylistId();
$this->collCcShowsRelatedByDbAutoPlaylistIdPartial = true;
}
if (!in_array($l, $this->collCcShows->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
$this->doAddCcShow($l);
if (!in_array($l, $this->collCcShowsRelatedByDbAutoPlaylistId->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
$this->doAddCcShowRelatedByDbAutoPlaylistId($l);
if ($this->ccShowsScheduledForDeletion and $this->ccShowsScheduledForDeletion->contains($l)) {
$this->ccShowsScheduledForDeletion->remove($this->ccShowsScheduledForDeletion->search($l));
if ($this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion and $this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion->contains($l)) {
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion->remove($this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion->search($l));
}
}
@ -1558,28 +1662,478 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
}
/**
* @param CcShow $ccShow The ccShow object to add.
* @param CcShowRelatedByDbAutoPlaylistId $ccShowRelatedByDbAutoPlaylistId The ccShowRelatedByDbAutoPlaylistId object to add.
*/
protected function doAddCcShow($ccShow)
protected function doAddCcShowRelatedByDbAutoPlaylistId($ccShowRelatedByDbAutoPlaylistId)
{
$this->collCcShows[]= $ccShow;
$ccShow->setCcPlaylist($this);
$this->collCcShowsRelatedByDbAutoPlaylistId[]= $ccShowRelatedByDbAutoPlaylistId;
$ccShowRelatedByDbAutoPlaylistId->setCcPlaylistRelatedByDbAutoPlaylistId($this);
}
/**
* @param CcShow $ccShow The ccShow object to remove.
* @param CcShowRelatedByDbAutoPlaylistId $ccShowRelatedByDbAutoPlaylistId The ccShowRelatedByDbAutoPlaylistId object to remove.
* @return CcPlaylist The current object (for fluent API support)
*/
public function removeCcShow($ccShow)
public function removeCcShowRelatedByDbAutoPlaylistId($ccShowRelatedByDbAutoPlaylistId)
{
if ($this->getCcShows()->contains($ccShow)) {
$this->collCcShows->remove($this->collCcShows->search($ccShow));
if (null === $this->ccShowsScheduledForDeletion) {
$this->ccShowsScheduledForDeletion = clone $this->collCcShows;
$this->ccShowsScheduledForDeletion->clear();
if ($this->getCcShowsRelatedByDbAutoPlaylistId()->contains($ccShowRelatedByDbAutoPlaylistId)) {
$this->collCcShowsRelatedByDbAutoPlaylistId->remove($this->collCcShowsRelatedByDbAutoPlaylistId->search($ccShowRelatedByDbAutoPlaylistId));
if (null === $this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion) {
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion = clone $this->collCcShowsRelatedByDbAutoPlaylistId;
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion->clear();
}
$this->ccShowsScheduledForDeletion[]= $ccShow;
$ccShow->setCcPlaylist(null);
$this->ccShowsRelatedByDbAutoPlaylistIdScheduledForDeletion[]= $ccShowRelatedByDbAutoPlaylistId;
$ccShowRelatedByDbAutoPlaylistId->setCcPlaylistRelatedByDbAutoPlaylistId(null);
}
return $this;
}
/**
* Clears out the collCcShowsRelatedByDbIntroPlaylistId collection
*
* This does not modify the database; however, it will remove any associated objects, causing
* them to be refetched by subsequent calls to accessor method.
*
* @return CcPlaylist The current object (for fluent API support)
* @see addCcShowsRelatedByDbIntroPlaylistId()
*/
public function clearCcShowsRelatedByDbIntroPlaylistId()
{
$this->collCcShowsRelatedByDbIntroPlaylistId = null; // important to set this to null since that means it is uninitialized
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = null;
return $this;
}
/**
* reset is the collCcShowsRelatedByDbIntroPlaylistId collection loaded partially
*
* @return void
*/
public function resetPartialCcShowsRelatedByDbIntroPlaylistId($v = true)
{
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = $v;
}
/**
* Initializes the collCcShowsRelatedByDbIntroPlaylistId collection.
*
* By default this just sets the collCcShowsRelatedByDbIntroPlaylistId collection to an empty array (like clearcollCcShowsRelatedByDbIntroPlaylistId());
* however, you may wish to override this method in your stub class to provide setting appropriate
* to your application -- for example, setting the initial array to the values stored in database.
*
* @param boolean $overrideExisting If set to true, the method call initializes
* the collection even if it is not empty
*
* @return void
*/
public function initCcShowsRelatedByDbIntroPlaylistId($overrideExisting = true)
{
if (null !== $this->collCcShowsRelatedByDbIntroPlaylistId && !$overrideExisting) {
return;
}
$this->collCcShowsRelatedByDbIntroPlaylistId = new PropelObjectCollection();
$this->collCcShowsRelatedByDbIntroPlaylistId->setModel('CcShow');
}
/**
* Gets an array of CcShow objects which contain a foreign key that references this object.
*
* If the $criteria is not null, it is used to always fetch the results from the database.
* Otherwise the results are fetched from the database the first time, then cached.
* Next time the same method is called without $criteria, the cached collection is returned.
* If this CcPlaylist is new, it will return
* an empty collection or the current collection; the criteria is ignored on a new object.
*
* @param Criteria $criteria optional Criteria object to narrow the query
* @param PropelPDO $con optional connection object
* @return PropelObjectCollection|CcShow[] List of CcShow objects
* @throws PropelException
*/
public function getCcShowsRelatedByDbIntroPlaylistId($criteria = null, PropelPDO $con = null)
{
$partial = $this->collCcShowsRelatedByDbIntroPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbIntroPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbIntroPlaylistId) {
// return empty collection
$this->initCcShowsRelatedByDbIntroPlaylistId();
} else {
$collCcShowsRelatedByDbIntroPlaylistId = CcShowQuery::create(null, $criteria)
->filterByCcPlaylistRelatedByDbIntroPlaylistId($this)
->find($con);
if (null !== $criteria) {
if (false !== $this->collCcShowsRelatedByDbIntroPlaylistIdPartial && count($collCcShowsRelatedByDbIntroPlaylistId)) {
$this->initCcShowsRelatedByDbIntroPlaylistId(false);
foreach ($collCcShowsRelatedByDbIntroPlaylistId as $obj) {
if (false == $this->collCcShowsRelatedByDbIntroPlaylistId->contains($obj)) {
$this->collCcShowsRelatedByDbIntroPlaylistId->append($obj);
}
}
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = true;
}
$collCcShowsRelatedByDbIntroPlaylistId->getInternalIterator()->rewind();
return $collCcShowsRelatedByDbIntroPlaylistId;
}
if ($partial && $this->collCcShowsRelatedByDbIntroPlaylistId) {
foreach ($this->collCcShowsRelatedByDbIntroPlaylistId as $obj) {
if ($obj->isNew()) {
$collCcShowsRelatedByDbIntroPlaylistId[] = $obj;
}
}
}
$this->collCcShowsRelatedByDbIntroPlaylistId = $collCcShowsRelatedByDbIntroPlaylistId;
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = false;
}
}
return $this->collCcShowsRelatedByDbIntroPlaylistId;
}
/**
* Sets a collection of CcShowRelatedByDbIntroPlaylistId objects related by a one-to-many relationship
* to the current object.
* It will also schedule objects for deletion based on a diff between old objects (aka persisted)
* and new objects from the given Propel collection.
*
* @param PropelCollection $ccShowsRelatedByDbIntroPlaylistId A Propel collection.
* @param PropelPDO $con Optional connection object
* @return CcPlaylist The current object (for fluent API support)
*/
public function setCcShowsRelatedByDbIntroPlaylistId(PropelCollection $ccShowsRelatedByDbIntroPlaylistId, PropelPDO $con = null)
{
$ccShowsRelatedByDbIntroPlaylistIdToDelete = $this->getCcShowsRelatedByDbIntroPlaylistId(new Criteria(), $con)->diff($ccShowsRelatedByDbIntroPlaylistId);
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion = $ccShowsRelatedByDbIntroPlaylistIdToDelete;
foreach ($ccShowsRelatedByDbIntroPlaylistIdToDelete as $ccShowRelatedByDbIntroPlaylistIdRemoved) {
$ccShowRelatedByDbIntroPlaylistIdRemoved->setCcPlaylistRelatedByDbIntroPlaylistId(null);
}
$this->collCcShowsRelatedByDbIntroPlaylistId = null;
foreach ($ccShowsRelatedByDbIntroPlaylistId as $ccShowRelatedByDbIntroPlaylistId) {
$this->addCcShowRelatedByDbIntroPlaylistId($ccShowRelatedByDbIntroPlaylistId);
}
$this->collCcShowsRelatedByDbIntroPlaylistId = $ccShowsRelatedByDbIntroPlaylistId;
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = false;
return $this;
}
/**
* Returns the number of related CcShow objects.
*
* @param Criteria $criteria
* @param boolean $distinct
* @param PropelPDO $con
* @return int Count of related CcShow objects.
* @throws PropelException
*/
public function countCcShowsRelatedByDbIntroPlaylistId(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
{
$partial = $this->collCcShowsRelatedByDbIntroPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbIntroPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbIntroPlaylistId) {
return 0;
}
if ($partial && !$criteria) {
return count($this->getCcShowsRelatedByDbIntroPlaylistId());
}
$query = CcShowQuery::create(null, $criteria);
if ($distinct) {
$query->distinct();
}
return $query
->filterByCcPlaylistRelatedByDbIntroPlaylistId($this)
->count($con);
}
return count($this->collCcShowsRelatedByDbIntroPlaylistId);
}
/**
* Method called to associate a CcShow object to this object
* through the CcShow foreign key attribute.
*
* @param CcShow $l CcShow
* @return CcPlaylist The current object (for fluent API support)
*/
public function addCcShowRelatedByDbIntroPlaylistId(CcShow $l)
{
if ($this->collCcShowsRelatedByDbIntroPlaylistId === null) {
$this->initCcShowsRelatedByDbIntroPlaylistId();
$this->collCcShowsRelatedByDbIntroPlaylistIdPartial = true;
}
if (!in_array($l, $this->collCcShowsRelatedByDbIntroPlaylistId->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
$this->doAddCcShowRelatedByDbIntroPlaylistId($l);
if ($this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion and $this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion->contains($l)) {
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion->remove($this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion->search($l));
}
}
return $this;
}
/**
* @param CcShowRelatedByDbIntroPlaylistId $ccShowRelatedByDbIntroPlaylistId The ccShowRelatedByDbIntroPlaylistId object to add.
*/
protected function doAddCcShowRelatedByDbIntroPlaylistId($ccShowRelatedByDbIntroPlaylistId)
{
$this->collCcShowsRelatedByDbIntroPlaylistId[]= $ccShowRelatedByDbIntroPlaylistId;
$ccShowRelatedByDbIntroPlaylistId->setCcPlaylistRelatedByDbIntroPlaylistId($this);
}
/**
* @param CcShowRelatedByDbIntroPlaylistId $ccShowRelatedByDbIntroPlaylistId The ccShowRelatedByDbIntroPlaylistId object to remove.
* @return CcPlaylist The current object (for fluent API support)
*/
public function removeCcShowRelatedByDbIntroPlaylistId($ccShowRelatedByDbIntroPlaylistId)
{
if ($this->getCcShowsRelatedByDbIntroPlaylistId()->contains($ccShowRelatedByDbIntroPlaylistId)) {
$this->collCcShowsRelatedByDbIntroPlaylistId->remove($this->collCcShowsRelatedByDbIntroPlaylistId->search($ccShowRelatedByDbIntroPlaylistId));
if (null === $this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion) {
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion = clone $this->collCcShowsRelatedByDbIntroPlaylistId;
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion->clear();
}
$this->ccShowsRelatedByDbIntroPlaylistIdScheduledForDeletion[]= $ccShowRelatedByDbIntroPlaylistId;
$ccShowRelatedByDbIntroPlaylistId->setCcPlaylistRelatedByDbIntroPlaylistId(null);
}
return $this;
}
/**
* Clears out the collCcShowsRelatedByDbOutroPlaylistId collection
*
* This does not modify the database; however, it will remove any associated objects, causing
* them to be refetched by subsequent calls to accessor method.
*
* @return CcPlaylist The current object (for fluent API support)
* @see addCcShowsRelatedByDbOutroPlaylistId()
*/
public function clearCcShowsRelatedByDbOutroPlaylistId()
{
$this->collCcShowsRelatedByDbOutroPlaylistId = null; // important to set this to null since that means it is uninitialized
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = null;
return $this;
}
/**
* reset is the collCcShowsRelatedByDbOutroPlaylistId collection loaded partially
*
* @return void
*/
public function resetPartialCcShowsRelatedByDbOutroPlaylistId($v = true)
{
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = $v;
}
/**
* Initializes the collCcShowsRelatedByDbOutroPlaylistId collection.
*
* By default this just sets the collCcShowsRelatedByDbOutroPlaylistId collection to an empty array (like clearcollCcShowsRelatedByDbOutroPlaylistId());
* however, you may wish to override this method in your stub class to provide setting appropriate
* to your application -- for example, setting the initial array to the values stored in database.
*
* @param boolean $overrideExisting If set to true, the method call initializes
* the collection even if it is not empty
*
* @return void
*/
public function initCcShowsRelatedByDbOutroPlaylistId($overrideExisting = true)
{
if (null !== $this->collCcShowsRelatedByDbOutroPlaylistId && !$overrideExisting) {
return;
}
$this->collCcShowsRelatedByDbOutroPlaylistId = new PropelObjectCollection();
$this->collCcShowsRelatedByDbOutroPlaylistId->setModel('CcShow');
}
/**
* Gets an array of CcShow objects which contain a foreign key that references this object.
*
* If the $criteria is not null, it is used to always fetch the results from the database.
* Otherwise the results are fetched from the database the first time, then cached.
* Next time the same method is called without $criteria, the cached collection is returned.
* If this CcPlaylist is new, it will return
* an empty collection or the current collection; the criteria is ignored on a new object.
*
* @param Criteria $criteria optional Criteria object to narrow the query
* @param PropelPDO $con optional connection object
* @return PropelObjectCollection|CcShow[] List of CcShow objects
* @throws PropelException
*/
public function getCcShowsRelatedByDbOutroPlaylistId($criteria = null, PropelPDO $con = null)
{
$partial = $this->collCcShowsRelatedByDbOutroPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbOutroPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbOutroPlaylistId) {
// return empty collection
$this->initCcShowsRelatedByDbOutroPlaylistId();
} else {
$collCcShowsRelatedByDbOutroPlaylistId = CcShowQuery::create(null, $criteria)
->filterByCcPlaylistRelatedByDbOutroPlaylistId($this)
->find($con);
if (null !== $criteria) {
if (false !== $this->collCcShowsRelatedByDbOutroPlaylistIdPartial && count($collCcShowsRelatedByDbOutroPlaylistId)) {
$this->initCcShowsRelatedByDbOutroPlaylistId(false);
foreach ($collCcShowsRelatedByDbOutroPlaylistId as $obj) {
if (false == $this->collCcShowsRelatedByDbOutroPlaylistId->contains($obj)) {
$this->collCcShowsRelatedByDbOutroPlaylistId->append($obj);
}
}
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = true;
}
$collCcShowsRelatedByDbOutroPlaylistId->getInternalIterator()->rewind();
return $collCcShowsRelatedByDbOutroPlaylistId;
}
if ($partial && $this->collCcShowsRelatedByDbOutroPlaylistId) {
foreach ($this->collCcShowsRelatedByDbOutroPlaylistId as $obj) {
if ($obj->isNew()) {
$collCcShowsRelatedByDbOutroPlaylistId[] = $obj;
}
}
}
$this->collCcShowsRelatedByDbOutroPlaylistId = $collCcShowsRelatedByDbOutroPlaylistId;
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = false;
}
}
return $this->collCcShowsRelatedByDbOutroPlaylistId;
}
/**
* Sets a collection of CcShowRelatedByDbOutroPlaylistId objects related by a one-to-many relationship
* to the current object.
* It will also schedule objects for deletion based on a diff between old objects (aka persisted)
* and new objects from the given Propel collection.
*
* @param PropelCollection $ccShowsRelatedByDbOutroPlaylistId A Propel collection.
* @param PropelPDO $con Optional connection object
* @return CcPlaylist The current object (for fluent API support)
*/
public function setCcShowsRelatedByDbOutroPlaylistId(PropelCollection $ccShowsRelatedByDbOutroPlaylistId, PropelPDO $con = null)
{
$ccShowsRelatedByDbOutroPlaylistIdToDelete = $this->getCcShowsRelatedByDbOutroPlaylistId(new Criteria(), $con)->diff($ccShowsRelatedByDbOutroPlaylistId);
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion = $ccShowsRelatedByDbOutroPlaylistIdToDelete;
foreach ($ccShowsRelatedByDbOutroPlaylistIdToDelete as $ccShowRelatedByDbOutroPlaylistIdRemoved) {
$ccShowRelatedByDbOutroPlaylistIdRemoved->setCcPlaylistRelatedByDbOutroPlaylistId(null);
}
$this->collCcShowsRelatedByDbOutroPlaylistId = null;
foreach ($ccShowsRelatedByDbOutroPlaylistId as $ccShowRelatedByDbOutroPlaylistId) {
$this->addCcShowRelatedByDbOutroPlaylistId($ccShowRelatedByDbOutroPlaylistId);
}
$this->collCcShowsRelatedByDbOutroPlaylistId = $ccShowsRelatedByDbOutroPlaylistId;
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = false;
return $this;
}
/**
* Returns the number of related CcShow objects.
*
* @param Criteria $criteria
* @param boolean $distinct
* @param PropelPDO $con
* @return int Count of related CcShow objects.
* @throws PropelException
*/
public function countCcShowsRelatedByDbOutroPlaylistId(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
{
$partial = $this->collCcShowsRelatedByDbOutroPlaylistIdPartial && !$this->isNew();
if (null === $this->collCcShowsRelatedByDbOutroPlaylistId || null !== $criteria || $partial) {
if ($this->isNew() && null === $this->collCcShowsRelatedByDbOutroPlaylistId) {
return 0;
}
if ($partial && !$criteria) {
return count($this->getCcShowsRelatedByDbOutroPlaylistId());
}
$query = CcShowQuery::create(null, $criteria);
if ($distinct) {
$query->distinct();
}
return $query
->filterByCcPlaylistRelatedByDbOutroPlaylistId($this)
->count($con);
}
return count($this->collCcShowsRelatedByDbOutroPlaylistId);
}
/**
* Method called to associate a CcShow object to this object
* through the CcShow foreign key attribute.
*
* @param CcShow $l CcShow
* @return CcPlaylist The current object (for fluent API support)
*/
public function addCcShowRelatedByDbOutroPlaylistId(CcShow $l)
{
if ($this->collCcShowsRelatedByDbOutroPlaylistId === null) {
$this->initCcShowsRelatedByDbOutroPlaylistId();
$this->collCcShowsRelatedByDbOutroPlaylistIdPartial = true;
}
if (!in_array($l, $this->collCcShowsRelatedByDbOutroPlaylistId->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
$this->doAddCcShowRelatedByDbOutroPlaylistId($l);
if ($this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion and $this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion->contains($l)) {
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion->remove($this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion->search($l));
}
}
return $this;
}
/**
* @param CcShowRelatedByDbOutroPlaylistId $ccShowRelatedByDbOutroPlaylistId The ccShowRelatedByDbOutroPlaylistId object to add.
*/
protected function doAddCcShowRelatedByDbOutroPlaylistId($ccShowRelatedByDbOutroPlaylistId)
{
$this->collCcShowsRelatedByDbOutroPlaylistId[]= $ccShowRelatedByDbOutroPlaylistId;
$ccShowRelatedByDbOutroPlaylistId->setCcPlaylistRelatedByDbOutroPlaylistId($this);
}
/**
* @param CcShowRelatedByDbOutroPlaylistId $ccShowRelatedByDbOutroPlaylistId The ccShowRelatedByDbOutroPlaylistId object to remove.
* @return CcPlaylist The current object (for fluent API support)
*/
public function removeCcShowRelatedByDbOutroPlaylistId($ccShowRelatedByDbOutroPlaylistId)
{
if ($this->getCcShowsRelatedByDbOutroPlaylistId()->contains($ccShowRelatedByDbOutroPlaylistId)) {
$this->collCcShowsRelatedByDbOutroPlaylistId->remove($this->collCcShowsRelatedByDbOutroPlaylistId->search($ccShowRelatedByDbOutroPlaylistId));
if (null === $this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion) {
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion = clone $this->collCcShowsRelatedByDbOutroPlaylistId;
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion->clear();
}
$this->ccShowsRelatedByDbOutroPlaylistIdScheduledForDeletion[]= $ccShowRelatedByDbOutroPlaylistId;
$ccShowRelatedByDbOutroPlaylistId->setCcPlaylistRelatedByDbOutroPlaylistId(null);
}
return $this;
@ -1895,8 +2449,18 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
{
if ($deep && !$this->alreadyInClearAllReferencesDeep) {
$this->alreadyInClearAllReferencesDeep = true;
if ($this->collCcShows) {
foreach ($this->collCcShows as $o) {
if ($this->collCcShowsRelatedByDbAutoPlaylistId) {
foreach ($this->collCcShowsRelatedByDbAutoPlaylistId as $o) {
$o->clearAllReferences($deep);
}
}
if ($this->collCcShowsRelatedByDbIntroPlaylistId) {
foreach ($this->collCcShowsRelatedByDbIntroPlaylistId as $o) {
$o->clearAllReferences($deep);
}
}
if ($this->collCcShowsRelatedByDbOutroPlaylistId) {
foreach ($this->collCcShowsRelatedByDbOutroPlaylistId as $o) {
$o->clearAllReferences($deep);
}
}
@ -1912,10 +2476,18 @@ abstract class BaseCcPlaylist extends BaseObject implements Persistent
$this->alreadyInClearAllReferencesDeep = false;
} // if ($deep)
if ($this->collCcShows instanceof PropelCollection) {
$this->collCcShows->clearIterator();
if ($this->collCcShowsRelatedByDbAutoPlaylistId instanceof PropelCollection) {
$this->collCcShowsRelatedByDbAutoPlaylistId->clearIterator();
}
$this->collCcShows = null;
$this->collCcShowsRelatedByDbAutoPlaylistId = null;
if ($this->collCcShowsRelatedByDbIntroPlaylistId instanceof PropelCollection) {
$this->collCcShowsRelatedByDbIntroPlaylistId->clearIterator();
}
$this->collCcShowsRelatedByDbIntroPlaylistId = null;
if ($this->collCcShowsRelatedByDbOutroPlaylistId instanceof PropelCollection) {
$this->collCcShowsRelatedByDbOutroPlaylistId->clearIterator();
}
$this->collCcShowsRelatedByDbOutroPlaylistId = null;
if ($this->collCcPlaylistcontentss instanceof PropelCollection) {
$this->collCcPlaylistcontentss->clearIterator();
}

View File

@ -385,6 +385,12 @@ abstract class BaseCcPlaylistPeer
*/
public static function clearRelatedInstancePool()
{
// Invalidate objects in CcShowPeer instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
CcShowPeer::clearInstancePool();
// Invalidate objects in CcShowPeer instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
CcShowPeer::clearInstancePool();
// Invalidate objects in CcShowPeer instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
CcShowPeer::clearInstancePool();

View File

@ -30,9 +30,17 @@
* @method CcPlaylistQuery rightJoinCcSubjs($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcSubjs relation
* @method CcPlaylistQuery innerJoinCcSubjs($relationAlias = null) Adds a INNER JOIN clause to the query using the CcSubjs relation
*
* @method CcPlaylistQuery leftJoinCcShow($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcShow relation
* @method CcPlaylistQuery rightJoinCcShow($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcShow relation
* @method CcPlaylistQuery innerJoinCcShow($relationAlias = null) Adds a INNER JOIN clause to the query using the CcShow relation
* @method CcPlaylistQuery leftJoinCcShowRelatedByDbAutoPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcShowRelatedByDbAutoPlaylistId relation
* @method CcPlaylistQuery rightJoinCcShowRelatedByDbAutoPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcShowRelatedByDbAutoPlaylistId relation
* @method CcPlaylistQuery innerJoinCcShowRelatedByDbAutoPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcShowRelatedByDbAutoPlaylistId relation
*
* @method CcPlaylistQuery leftJoinCcShowRelatedByDbIntroPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcShowRelatedByDbIntroPlaylistId relation
* @method CcPlaylistQuery rightJoinCcShowRelatedByDbIntroPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcShowRelatedByDbIntroPlaylistId relation
* @method CcPlaylistQuery innerJoinCcShowRelatedByDbIntroPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcShowRelatedByDbIntroPlaylistId relation
*
* @method CcPlaylistQuery leftJoinCcShowRelatedByDbOutroPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcShowRelatedByDbOutroPlaylistId relation
* @method CcPlaylistQuery rightJoinCcShowRelatedByDbOutroPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcShowRelatedByDbOutroPlaylistId relation
* @method CcPlaylistQuery innerJoinCcShowRelatedByDbOutroPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcShowRelatedByDbOutroPlaylistId relation
*
* @method CcPlaylistQuery leftJoinCcPlaylistcontents($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcPlaylistcontents relation
* @method CcPlaylistQuery rightJoinCcPlaylistcontents($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcPlaylistcontents relation
@ -595,33 +603,33 @@ abstract class BaseCcPlaylistQuery extends ModelCriteria
* @return CcPlaylistQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcShow($ccShow, $comparison = null)
public function filterByCcShowRelatedByDbAutoPlaylistId($ccShow, $comparison = null)
{
if ($ccShow instanceof CcShow) {
return $this
->addUsingAlias(CcPlaylistPeer::ID, $ccShow->getDbAutoPlaylistId(), $comparison);
} elseif ($ccShow instanceof PropelObjectCollection) {
return $this
->useCcShowQuery()
->useCcShowRelatedByDbAutoPlaylistIdQuery()
->filterByPrimaryKeys($ccShow->getPrimaryKeys())
->endUse();
} else {
throw new PropelException('filterByCcShow() only accepts arguments of type CcShow or PropelCollection');
throw new PropelException('filterByCcShowRelatedByDbAutoPlaylistId() only accepts arguments of type CcShow or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcShow relation
* Adds a JOIN clause to the query using the CcShowRelatedByDbAutoPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcPlaylistQuery The current query, for fluid interface
*/
public function joinCcShow($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
public function joinCcShowRelatedByDbAutoPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcShow');
$relationMap = $tableMap->getRelation('CcShowRelatedByDbAutoPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
@ -636,14 +644,14 @@ abstract class BaseCcPlaylistQuery extends ModelCriteria
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcShow');
$this->addJoinObject($join, 'CcShowRelatedByDbAutoPlaylistId');
}
return $this;
}
/**
* Use the CcShow relation CcShow object
* Use the CcShowRelatedByDbAutoPlaylistId relation CcShow object
*
* @see useQuery()
*
@ -653,11 +661,159 @@ abstract class BaseCcPlaylistQuery extends ModelCriteria
*
* @return CcShowQuery A secondary query class using the current class as primary query
*/
public function useCcShowQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
public function useCcShowRelatedByDbAutoPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcShow($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcShow', 'CcShowQuery');
->joinCcShowRelatedByDbAutoPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcShowRelatedByDbAutoPlaylistId', 'CcShowQuery');
}
/**
* Filter the query by a related CcShow object
*
* @param CcShow|PropelObjectCollection $ccShow the related object to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcPlaylistQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcShowRelatedByDbIntroPlaylistId($ccShow, $comparison = null)
{
if ($ccShow instanceof CcShow) {
return $this
->addUsingAlias(CcPlaylistPeer::ID, $ccShow->getDbIntroPlaylistId(), $comparison);
} elseif ($ccShow instanceof PropelObjectCollection) {
return $this
->useCcShowRelatedByDbIntroPlaylistIdQuery()
->filterByPrimaryKeys($ccShow->getPrimaryKeys())
->endUse();
} else {
throw new PropelException('filterByCcShowRelatedByDbIntroPlaylistId() only accepts arguments of type CcShow or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcShowRelatedByDbIntroPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcPlaylistQuery The current query, for fluid interface
*/
public function joinCcShowRelatedByDbIntroPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcShowRelatedByDbIntroPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if ($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcShowRelatedByDbIntroPlaylistId');
}
return $this;
}
/**
* Use the CcShowRelatedByDbIntroPlaylistId relation CcShow object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcShowQuery A secondary query class using the current class as primary query
*/
public function useCcShowRelatedByDbIntroPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcShowRelatedByDbIntroPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcShowRelatedByDbIntroPlaylistId', 'CcShowQuery');
}
/**
* Filter the query by a related CcShow object
*
* @param CcShow|PropelObjectCollection $ccShow the related object to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcPlaylistQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcShowRelatedByDbOutroPlaylistId($ccShow, $comparison = null)
{
if ($ccShow instanceof CcShow) {
return $this
->addUsingAlias(CcPlaylistPeer::ID, $ccShow->getDbOutroPlaylistId(), $comparison);
} elseif ($ccShow instanceof PropelObjectCollection) {
return $this
->useCcShowRelatedByDbOutroPlaylistIdQuery()
->filterByPrimaryKeys($ccShow->getPrimaryKeys())
->endUse();
} else {
throw new PropelException('filterByCcShowRelatedByDbOutroPlaylistId() only accepts arguments of type CcShow or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcShowRelatedByDbOutroPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcPlaylistQuery The current query, for fluid interface
*/
public function joinCcShowRelatedByDbOutroPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcShowRelatedByDbOutroPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if ($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcShowRelatedByDbOutroPlaylistId');
}
return $this;
}
/**
* Use the CcShowRelatedByDbOutroPlaylistId relation CcShow object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcShowQuery A secondary query class using the current class as primary query
*/
public function useCcShowRelatedByDbOutroPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcShowRelatedByDbOutroPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcShowRelatedByDbOutroPlaylistId', 'CcShowQuery');
}
/**

View File

@ -141,10 +141,46 @@ abstract class BaseCcShow extends BaseObject implements Persistent
*/
protected $autoplaylist_repeat;
/**
* The value for the override_intro_playlist field.
* Note: this column has a database default value of: false
* @var boolean
*/
protected $override_intro_playlist;
/**
* The value for the intro_playlist_id field.
* @var int
*/
protected $intro_playlist_id;
/**
* The value for the override_outro_playlist field.
* Note: this column has a database default value of: false
* @var boolean
*/
protected $override_outro_playlist;
/**
* The value for the outro_playlist_id field.
* @var int
*/
protected $outro_playlist_id;
/**
* @var CcPlaylist
*/
protected $aCcPlaylist;
protected $aCcPlaylistRelatedByDbAutoPlaylistId;
/**
* @var CcPlaylist
*/
protected $aCcPlaylistRelatedByDbIntroPlaylistId;
/**
* @var CcPlaylist
*/
protected $aCcPlaylistRelatedByDbOutroPlaylistId;
/**
* @var PropelObjectCollection|CcShowInstances[] Collection to store aggregation of CcShowInstances objects.
@ -232,6 +268,8 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->image_path = '';
$this->has_autoplaylist = false;
$this->autoplaylist_repeat = false;
$this->override_intro_playlist = false;
$this->override_outro_playlist = false;
}
/**
@ -431,6 +469,50 @@ abstract class BaseCcShow extends BaseObject implements Persistent
return $this->autoplaylist_repeat;
}
/**
* Get the [override_intro_playlist] column value.
*
* @return boolean
*/
public function getDbOverrideIntroPlaylist()
{
return $this->override_intro_playlist;
}
/**
* Get the [intro_playlist_id] column value.
*
* @return int
*/
public function getDbIntroPlaylistId()
{
return $this->intro_playlist_id;
}
/**
* Get the [override_outro_playlist] column value.
*
* @return boolean
*/
public function getDbOverrideOutroPlaylist()
{
return $this->override_outro_playlist;
}
/**
* Get the [outro_playlist_id] column value.
*
* @return int
*/
public function getDbOutroPlaylistId()
{
return $this->outro_playlist_id;
}
/**
* Set the value of [id] column.
*
@ -803,8 +885,8 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->modifiedColumns[] = CcShowPeer::AUTOPLAYLIST_ID;
}
if ($this->aCcPlaylist !== null && $this->aCcPlaylist->getDbId() !== $v) {
$this->aCcPlaylist = null;
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId !== null && $this->aCcPlaylistRelatedByDbAutoPlaylistId->getDbId() !== $v) {
$this->aCcPlaylistRelatedByDbAutoPlaylistId = null;
}
@ -840,6 +922,114 @@ abstract class BaseCcShow extends BaseObject implements Persistent
return $this;
} // setDbAutoPlaylistRepeat()
/**
* Sets the value of the [override_intro_playlist] column.
* Non-boolean arguments are converted using the following rules:
* * 1, '1', 'true', 'on', and 'yes' are converted to boolean true
* * 0, '0', 'false', 'off', and 'no' are converted to boolean false
* Check on string values is case insensitive (so 'FaLsE' is seen as 'false').
*
* @param boolean|integer|string $v The new value
* @return CcShow The current object (for fluent API support)
*/
public function setDbOverrideIntroPlaylist($v)
{
if ($v !== null) {
if (is_string($v)) {
$v = in_array(strtolower($v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
} else {
$v = (boolean) $v;
}
}
if ($this->override_intro_playlist !== $v) {
$this->override_intro_playlist = $v;
$this->modifiedColumns[] = CcShowPeer::OVERRIDE_INTRO_PLAYLIST;
}
return $this;
} // setDbOverrideIntroPlaylist()
/**
* Set the value of [intro_playlist_id] column.
*
* @param int $v new value
* @return CcShow The current object (for fluent API support)
*/
public function setDbIntroPlaylistId($v)
{
if ($v !== null && is_numeric($v)) {
$v = (int) $v;
}
if ($this->intro_playlist_id !== $v) {
$this->intro_playlist_id = $v;
$this->modifiedColumns[] = CcShowPeer::INTRO_PLAYLIST_ID;
}
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId !== null && $this->aCcPlaylistRelatedByDbIntroPlaylistId->getDbId() !== $v) {
$this->aCcPlaylistRelatedByDbIntroPlaylistId = null;
}
return $this;
} // setDbIntroPlaylistId()
/**
* Sets the value of the [override_outro_playlist] column.
* Non-boolean arguments are converted using the following rules:
* * 1, '1', 'true', 'on', and 'yes' are converted to boolean true
* * 0, '0', 'false', 'off', and 'no' are converted to boolean false
* Check on string values is case insensitive (so 'FaLsE' is seen as 'false').
*
* @param boolean|integer|string $v The new value
* @return CcShow The current object (for fluent API support)
*/
public function setDbOverrideOutroPlaylist($v)
{
if ($v !== null) {
if (is_string($v)) {
$v = in_array(strtolower($v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
} else {
$v = (boolean) $v;
}
}
if ($this->override_outro_playlist !== $v) {
$this->override_outro_playlist = $v;
$this->modifiedColumns[] = CcShowPeer::OVERRIDE_OUTRO_PLAYLIST;
}
return $this;
} // setDbOverrideOutroPlaylist()
/**
* Set the value of [outro_playlist_id] column.
*
* @param int $v new value
* @return CcShow The current object (for fluent API support)
*/
public function setDbOutroPlaylistId($v)
{
if ($v !== null && is_numeric($v)) {
$v = (int) $v;
}
if ($this->outro_playlist_id !== $v) {
$this->outro_playlist_id = $v;
$this->modifiedColumns[] = CcShowPeer::OUTRO_PLAYLIST_ID;
}
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId !== null && $this->aCcPlaylistRelatedByDbOutroPlaylistId->getDbId() !== $v) {
$this->aCcPlaylistRelatedByDbOutroPlaylistId = null;
}
return $this;
} // setDbOutroPlaylistId()
/**
* Indicates whether the columns in this object are only set to default values.
*
@ -890,6 +1080,14 @@ abstract class BaseCcShow extends BaseObject implements Persistent
return false;
}
if ($this->override_intro_playlist !== false) {
return false;
}
if ($this->override_outro_playlist !== false) {
return false;
}
// otherwise, everything was equal, so return true
return true;
} // hasOnlyDefaultValues()
@ -929,6 +1127,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->has_autoplaylist = ($row[$startcol + 14] !== null) ? (boolean) $row[$startcol + 14] : null;
$this->autoplaylist_id = ($row[$startcol + 15] !== null) ? (int) $row[$startcol + 15] : null;
$this->autoplaylist_repeat = ($row[$startcol + 16] !== null) ? (boolean) $row[$startcol + 16] : null;
$this->override_intro_playlist = ($row[$startcol + 17] !== null) ? (boolean) $row[$startcol + 17] : null;
$this->intro_playlist_id = ($row[$startcol + 18] !== null) ? (int) $row[$startcol + 18] : null;
$this->override_outro_playlist = ($row[$startcol + 19] !== null) ? (boolean) $row[$startcol + 19] : null;
$this->outro_playlist_id = ($row[$startcol + 20] !== null) ? (int) $row[$startcol + 20] : null;
$this->resetModified();
$this->setNew(false);
@ -938,7 +1140,7 @@ abstract class BaseCcShow extends BaseObject implements Persistent
}
$this->postHydrate($row, $startcol, $rehydrate);
return $startcol + 17; // 17 = CcShowPeer::NUM_HYDRATE_COLUMNS.
return $startcol + 21; // 21 = CcShowPeer::NUM_HYDRATE_COLUMNS.
} catch (Exception $e) {
throw new PropelException("Error populating CcShow object", $e);
@ -961,8 +1163,14 @@ abstract class BaseCcShow extends BaseObject implements Persistent
public function ensureConsistency()
{
if ($this->aCcPlaylist !== null && $this->autoplaylist_id !== $this->aCcPlaylist->getDbId()) {
$this->aCcPlaylist = null;
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId !== null && $this->autoplaylist_id !== $this->aCcPlaylistRelatedByDbAutoPlaylistId->getDbId()) {
$this->aCcPlaylistRelatedByDbAutoPlaylistId = null;
}
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId !== null && $this->intro_playlist_id !== $this->aCcPlaylistRelatedByDbIntroPlaylistId->getDbId()) {
$this->aCcPlaylistRelatedByDbIntroPlaylistId = null;
}
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId !== null && $this->outro_playlist_id !== $this->aCcPlaylistRelatedByDbOutroPlaylistId->getDbId()) {
$this->aCcPlaylistRelatedByDbOutroPlaylistId = null;
}
} // ensureConsistency
@ -1003,7 +1211,9 @@ abstract class BaseCcShow extends BaseObject implements Persistent
if ($deep) { // also de-associate any related objects?
$this->aCcPlaylist = null;
$this->aCcPlaylistRelatedByDbAutoPlaylistId = null;
$this->aCcPlaylistRelatedByDbIntroPlaylistId = null;
$this->aCcPlaylistRelatedByDbOutroPlaylistId = null;
$this->collCcShowInstancess = null;
$this->collCcShowDayss = null;
@ -1130,11 +1340,25 @@ abstract class BaseCcShow extends BaseObject implements Persistent
// method. This object relates to these object(s) by a
// foreign key reference.
if ($this->aCcPlaylist !== null) {
if ($this->aCcPlaylist->isModified() || $this->aCcPlaylist->isNew()) {
$affectedRows += $this->aCcPlaylist->save($con);
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId !== null) {
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId->isModified() || $this->aCcPlaylistRelatedByDbAutoPlaylistId->isNew()) {
$affectedRows += $this->aCcPlaylistRelatedByDbAutoPlaylistId->save($con);
}
$this->setCcPlaylist($this->aCcPlaylist);
$this->setCcPlaylistRelatedByDbAutoPlaylistId($this->aCcPlaylistRelatedByDbAutoPlaylistId);
}
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId !== null) {
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId->isModified() || $this->aCcPlaylistRelatedByDbIntroPlaylistId->isNew()) {
$affectedRows += $this->aCcPlaylistRelatedByDbIntroPlaylistId->save($con);
}
$this->setCcPlaylistRelatedByDbIntroPlaylistId($this->aCcPlaylistRelatedByDbIntroPlaylistId);
}
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId !== null) {
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId->isModified() || $this->aCcPlaylistRelatedByDbOutroPlaylistId->isNew()) {
$affectedRows += $this->aCcPlaylistRelatedByDbOutroPlaylistId->save($con);
}
$this->setCcPlaylistRelatedByDbOutroPlaylistId($this->aCcPlaylistRelatedByDbOutroPlaylistId);
}
if ($this->isNew() || $this->isModified()) {
@ -1303,6 +1527,18 @@ abstract class BaseCcShow extends BaseObject implements Persistent
if ($this->isColumnModified(CcShowPeer::AUTOPLAYLIST_REPEAT)) {
$modifiedColumns[':p' . $index++] = '"autoplaylist_repeat"';
}
if ($this->isColumnModified(CcShowPeer::OVERRIDE_INTRO_PLAYLIST)) {
$modifiedColumns[':p' . $index++] = '"override_intro_playlist"';
}
if ($this->isColumnModified(CcShowPeer::INTRO_PLAYLIST_ID)) {
$modifiedColumns[':p' . $index++] = '"intro_playlist_id"';
}
if ($this->isColumnModified(CcShowPeer::OVERRIDE_OUTRO_PLAYLIST)) {
$modifiedColumns[':p' . $index++] = '"override_outro_playlist"';
}
if ($this->isColumnModified(CcShowPeer::OUTRO_PLAYLIST_ID)) {
$modifiedColumns[':p' . $index++] = '"outro_playlist_id"';
}
$sql = sprintf(
'INSERT INTO "cc_show" (%s) VALUES (%s)',
@ -1365,6 +1601,18 @@ abstract class BaseCcShow extends BaseObject implements Persistent
case '"autoplaylist_repeat"':
$stmt->bindValue($identifier, $this->autoplaylist_repeat, PDO::PARAM_BOOL);
break;
case '"override_intro_playlist"':
$stmt->bindValue($identifier, $this->override_intro_playlist, PDO::PARAM_BOOL);
break;
case '"intro_playlist_id"':
$stmt->bindValue($identifier, $this->intro_playlist_id, PDO::PARAM_INT);
break;
case '"override_outro_playlist"':
$stmt->bindValue($identifier, $this->override_outro_playlist, PDO::PARAM_BOOL);
break;
case '"outro_playlist_id"':
$stmt->bindValue($identifier, $this->outro_playlist_id, PDO::PARAM_INT);
break;
}
}
$stmt->execute();
@ -1457,9 +1705,21 @@ abstract class BaseCcShow extends BaseObject implements Persistent
// method. This object relates to these object(s) by a
// foreign key reference.
if ($this->aCcPlaylist !== null) {
if (!$this->aCcPlaylist->validate($columns)) {
$failureMap = array_merge($failureMap, $this->aCcPlaylist->getValidationFailures());
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId !== null) {
if (!$this->aCcPlaylistRelatedByDbAutoPlaylistId->validate($columns)) {
$failureMap = array_merge($failureMap, $this->aCcPlaylistRelatedByDbAutoPlaylistId->getValidationFailures());
}
}
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId !== null) {
if (!$this->aCcPlaylistRelatedByDbIntroPlaylistId->validate($columns)) {
$failureMap = array_merge($failureMap, $this->aCcPlaylistRelatedByDbIntroPlaylistId->getValidationFailures());
}
}
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId !== null) {
if (!$this->aCcPlaylistRelatedByDbOutroPlaylistId->validate($columns)) {
$failureMap = array_merge($failureMap, $this->aCcPlaylistRelatedByDbOutroPlaylistId->getValidationFailures());
}
}
@ -1587,6 +1847,18 @@ abstract class BaseCcShow extends BaseObject implements Persistent
case 16:
return $this->getDbAutoPlaylistRepeat();
break;
case 17:
return $this->getDbOverrideIntroPlaylist();
break;
case 18:
return $this->getDbIntroPlaylistId();
break;
case 19:
return $this->getDbOverrideOutroPlaylist();
break;
case 20:
return $this->getDbOutroPlaylistId();
break;
default:
return null;
break;
@ -1633,6 +1905,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$keys[14] => $this->getDbHasAutoPlaylist(),
$keys[15] => $this->getDbAutoPlaylistId(),
$keys[16] => $this->getDbAutoPlaylistRepeat(),
$keys[17] => $this->getDbOverrideIntroPlaylist(),
$keys[18] => $this->getDbIntroPlaylistId(),
$keys[19] => $this->getDbOverrideOutroPlaylist(),
$keys[20] => $this->getDbOutroPlaylistId(),
);
$virtualColumns = $this->virtualColumns;
foreach ($virtualColumns as $key => $virtualColumn) {
@ -1640,8 +1916,14 @@ abstract class BaseCcShow extends BaseObject implements Persistent
}
if ($includeForeignObjects) {
if (null !== $this->aCcPlaylist) {
$result['CcPlaylist'] = $this->aCcPlaylist->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
if (null !== $this->aCcPlaylistRelatedByDbAutoPlaylistId) {
$result['CcPlaylistRelatedByDbAutoPlaylistId'] = $this->aCcPlaylistRelatedByDbAutoPlaylistId->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
}
if (null !== $this->aCcPlaylistRelatedByDbIntroPlaylistId) {
$result['CcPlaylistRelatedByDbIntroPlaylistId'] = $this->aCcPlaylistRelatedByDbIntroPlaylistId->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
}
if (null !== $this->aCcPlaylistRelatedByDbOutroPlaylistId) {
$result['CcPlaylistRelatedByDbOutroPlaylistId'] = $this->aCcPlaylistRelatedByDbOutroPlaylistId->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
}
if (null !== $this->collCcShowInstancess) {
$result['CcShowInstancess'] = $this->collCcShowInstancess->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
@ -1740,6 +2022,18 @@ abstract class BaseCcShow extends BaseObject implements Persistent
case 16:
$this->setDbAutoPlaylistRepeat($value);
break;
case 17:
$this->setDbOverrideIntroPlaylist($value);
break;
case 18:
$this->setDbIntroPlaylistId($value);
break;
case 19:
$this->setDbOverrideOutroPlaylist($value);
break;
case 20:
$this->setDbOutroPlaylistId($value);
break;
} // switch()
}
@ -1781,6 +2075,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
if (array_key_exists($keys[14], $arr)) $this->setDbHasAutoPlaylist($arr[$keys[14]]);
if (array_key_exists($keys[15], $arr)) $this->setDbAutoPlaylistId($arr[$keys[15]]);
if (array_key_exists($keys[16], $arr)) $this->setDbAutoPlaylistRepeat($arr[$keys[16]]);
if (array_key_exists($keys[17], $arr)) $this->setDbOverrideIntroPlaylist($arr[$keys[17]]);
if (array_key_exists($keys[18], $arr)) $this->setDbIntroPlaylistId($arr[$keys[18]]);
if (array_key_exists($keys[19], $arr)) $this->setDbOverrideOutroPlaylist($arr[$keys[19]]);
if (array_key_exists($keys[20], $arr)) $this->setDbOutroPlaylistId($arr[$keys[20]]);
}
/**
@ -1809,6 +2107,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
if ($this->isColumnModified(CcShowPeer::HAS_AUTOPLAYLIST)) $criteria->add(CcShowPeer::HAS_AUTOPLAYLIST, $this->has_autoplaylist);
if ($this->isColumnModified(CcShowPeer::AUTOPLAYLIST_ID)) $criteria->add(CcShowPeer::AUTOPLAYLIST_ID, $this->autoplaylist_id);
if ($this->isColumnModified(CcShowPeer::AUTOPLAYLIST_REPEAT)) $criteria->add(CcShowPeer::AUTOPLAYLIST_REPEAT, $this->autoplaylist_repeat);
if ($this->isColumnModified(CcShowPeer::OVERRIDE_INTRO_PLAYLIST)) $criteria->add(CcShowPeer::OVERRIDE_INTRO_PLAYLIST, $this->override_intro_playlist);
if ($this->isColumnModified(CcShowPeer::INTRO_PLAYLIST_ID)) $criteria->add(CcShowPeer::INTRO_PLAYLIST_ID, $this->intro_playlist_id);
if ($this->isColumnModified(CcShowPeer::OVERRIDE_OUTRO_PLAYLIST)) $criteria->add(CcShowPeer::OVERRIDE_OUTRO_PLAYLIST, $this->override_outro_playlist);
if ($this->isColumnModified(CcShowPeer::OUTRO_PLAYLIST_ID)) $criteria->add(CcShowPeer::OUTRO_PLAYLIST_ID, $this->outro_playlist_id);
return $criteria;
}
@ -1888,6 +2190,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$copyObj->setDbHasAutoPlaylist($this->getDbHasAutoPlaylist());
$copyObj->setDbAutoPlaylistId($this->getDbAutoPlaylistId());
$copyObj->setDbAutoPlaylistRepeat($this->getDbAutoPlaylistRepeat());
$copyObj->setDbOverrideIntroPlaylist($this->getDbOverrideIntroPlaylist());
$copyObj->setDbIntroPlaylistId($this->getDbIntroPlaylistId());
$copyObj->setDbOverrideOutroPlaylist($this->getDbOverrideOutroPlaylist());
$copyObj->setDbOutroPlaylistId($this->getDbOutroPlaylistId());
if ($deepCopy && !$this->startCopy) {
// important: temporarily setNew(false) because this affects the behavior of
@ -1977,7 +2283,7 @@ abstract class BaseCcShow extends BaseObject implements Persistent
* @return CcShow The current object (for fluent API support)
* @throws PropelException
*/
public function setCcPlaylist(CcPlaylist $v = null)
public function setCcPlaylistRelatedByDbAutoPlaylistId(CcPlaylist $v = null)
{
if ($v === null) {
$this->setDbAutoPlaylistId(NULL);
@ -1985,12 +2291,12 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->setDbAutoPlaylistId($v->getDbId());
}
$this->aCcPlaylist = $v;
$this->aCcPlaylistRelatedByDbAutoPlaylistId = $v;
// Add binding for other direction of this n:n relationship.
// If this object has already been added to the CcPlaylist object, it will not be re-added.
if ($v !== null) {
$v->addCcShow($this);
$v->addCcShowRelatedByDbAutoPlaylistId($this);
}
@ -2006,20 +2312,124 @@ abstract class BaseCcShow extends BaseObject implements Persistent
* @return CcPlaylist The associated CcPlaylist object.
* @throws PropelException
*/
public function getCcPlaylist(PropelPDO $con = null, $doQuery = true)
public function getCcPlaylistRelatedByDbAutoPlaylistId(PropelPDO $con = null, $doQuery = true)
{
if ($this->aCcPlaylist === null && ($this->autoplaylist_id !== null) && $doQuery) {
$this->aCcPlaylist = CcPlaylistQuery::create()->findPk($this->autoplaylist_id, $con);
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId === null && ($this->autoplaylist_id !== null) && $doQuery) {
$this->aCcPlaylistRelatedByDbAutoPlaylistId = CcPlaylistQuery::create()->findPk($this->autoplaylist_id, $con);
/* The following can be used additionally to
guarantee the related object contains a reference
to this object. This level of coupling may, however, be
undesirable since it could result in an only partially populated collection
in the referenced object.
$this->aCcPlaylist->addCcShows($this);
$this->aCcPlaylistRelatedByDbAutoPlaylistId->addCcShowsRelatedByDbAutoPlaylistId($this);
*/
}
return $this->aCcPlaylist;
return $this->aCcPlaylistRelatedByDbAutoPlaylistId;
}
/**
* Declares an association between this object and a CcPlaylist object.
*
* @param CcPlaylist $v
* @return CcShow The current object (for fluent API support)
* @throws PropelException
*/
public function setCcPlaylistRelatedByDbIntroPlaylistId(CcPlaylist $v = null)
{
if ($v === null) {
$this->setDbIntroPlaylistId(NULL);
} else {
$this->setDbIntroPlaylistId($v->getDbId());
}
$this->aCcPlaylistRelatedByDbIntroPlaylistId = $v;
// Add binding for other direction of this n:n relationship.
// If this object has already been added to the CcPlaylist object, it will not be re-added.
if ($v !== null) {
$v->addCcShowRelatedByDbIntroPlaylistId($this);
}
return $this;
}
/**
* Get the associated CcPlaylist object
*
* @param PropelPDO $con Optional Connection object.
* @param $doQuery Executes a query to get the object if required
* @return CcPlaylist The associated CcPlaylist object.
* @throws PropelException
*/
public function getCcPlaylistRelatedByDbIntroPlaylistId(PropelPDO $con = null, $doQuery = true)
{
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId === null && ($this->intro_playlist_id !== null) && $doQuery) {
$this->aCcPlaylistRelatedByDbIntroPlaylistId = CcPlaylistQuery::create()->findPk($this->intro_playlist_id, $con);
/* The following can be used additionally to
guarantee the related object contains a reference
to this object. This level of coupling may, however, be
undesirable since it could result in an only partially populated collection
in the referenced object.
$this->aCcPlaylistRelatedByDbIntroPlaylistId->addCcShowsRelatedByDbIntroPlaylistId($this);
*/
}
return $this->aCcPlaylistRelatedByDbIntroPlaylistId;
}
/**
* Declares an association between this object and a CcPlaylist object.
*
* @param CcPlaylist $v
* @return CcShow The current object (for fluent API support)
* @throws PropelException
*/
public function setCcPlaylistRelatedByDbOutroPlaylistId(CcPlaylist $v = null)
{
if ($v === null) {
$this->setDbOutroPlaylistId(NULL);
} else {
$this->setDbOutroPlaylistId($v->getDbId());
}
$this->aCcPlaylistRelatedByDbOutroPlaylistId = $v;
// Add binding for other direction of this n:n relationship.
// If this object has already been added to the CcPlaylist object, it will not be re-added.
if ($v !== null) {
$v->addCcShowRelatedByDbOutroPlaylistId($this);
}
return $this;
}
/**
* Get the associated CcPlaylist object
*
* @param PropelPDO $con Optional Connection object.
* @param $doQuery Executes a query to get the object if required
* @return CcPlaylist The associated CcPlaylist object.
* @throws PropelException
*/
public function getCcPlaylistRelatedByDbOutroPlaylistId(PropelPDO $con = null, $doQuery = true)
{
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId === null && ($this->outro_playlist_id !== null) && $doQuery) {
$this->aCcPlaylistRelatedByDbOutroPlaylistId = CcPlaylistQuery::create()->findPk($this->outro_playlist_id, $con);
/* The following can be used additionally to
guarantee the related object contains a reference
to this object. This level of coupling may, however, be
undesirable since it could result in an only partially populated collection
in the referenced object.
$this->aCcPlaylistRelatedByDbOutroPlaylistId->addCcShowsRelatedByDbOutroPlaylistId($this);
*/
}
return $this->aCcPlaylistRelatedByDbOutroPlaylistId;
}
@ -3044,6 +3454,10 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->has_autoplaylist = null;
$this->autoplaylist_id = null;
$this->autoplaylist_repeat = null;
$this->override_intro_playlist = null;
$this->intro_playlist_id = null;
$this->override_outro_playlist = null;
$this->outro_playlist_id = null;
$this->alreadyInSave = false;
$this->alreadyInValidation = false;
$this->alreadyInClearAllReferencesDeep = false;
@ -3087,8 +3501,14 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$o->clearAllReferences($deep);
}
}
if ($this->aCcPlaylist instanceof Persistent) {
$this->aCcPlaylist->clearAllReferences($deep);
if ($this->aCcPlaylistRelatedByDbAutoPlaylistId instanceof Persistent) {
$this->aCcPlaylistRelatedByDbAutoPlaylistId->clearAllReferences($deep);
}
if ($this->aCcPlaylistRelatedByDbIntroPlaylistId instanceof Persistent) {
$this->aCcPlaylistRelatedByDbIntroPlaylistId->clearAllReferences($deep);
}
if ($this->aCcPlaylistRelatedByDbOutroPlaylistId instanceof Persistent) {
$this->aCcPlaylistRelatedByDbOutroPlaylistId->clearAllReferences($deep);
}
$this->alreadyInClearAllReferencesDeep = false;
@ -3110,7 +3530,9 @@ abstract class BaseCcShow extends BaseObject implements Persistent
$this->collCcShowHostss->clearIterator();
}
$this->collCcShowHostss = null;
$this->aCcPlaylist = null;
$this->aCcPlaylistRelatedByDbAutoPlaylistId = null;
$this->aCcPlaylistRelatedByDbIntroPlaylistId = null;
$this->aCcPlaylistRelatedByDbOutroPlaylistId = null;
}
/**

View File

@ -24,13 +24,13 @@ abstract class BaseCcShowPeer
const TM_CLASS = 'CcShowTableMap';
/** The total number of columns. */
const NUM_COLUMNS = 17;
const NUM_COLUMNS = 21;
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0;
/** The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */
const NUM_HYDRATE_COLUMNS = 17;
const NUM_HYDRATE_COLUMNS = 21;
/** the column name for the id field */
const ID = 'cc_show.id';
@ -83,6 +83,18 @@ abstract class BaseCcShowPeer
/** the column name for the autoplaylist_repeat field */
const AUTOPLAYLIST_REPEAT = 'cc_show.autoplaylist_repeat';
/** the column name for the override_intro_playlist field */
const OVERRIDE_INTRO_PLAYLIST = 'cc_show.override_intro_playlist';
/** the column name for the intro_playlist_id field */
const INTRO_PLAYLIST_ID = 'cc_show.intro_playlist_id';
/** the column name for the override_outro_playlist field */
const OVERRIDE_OUTRO_PLAYLIST = 'cc_show.override_outro_playlist';
/** the column name for the outro_playlist_id field */
const OUTRO_PLAYLIST_ID = 'cc_show.outro_playlist_id';
/** The default string format for model objects of the related table **/
const DEFAULT_STRING_FORMAT = 'YAML';
@ -102,12 +114,12 @@ abstract class BaseCcShowPeer
* e.g. CcShowPeer::$fieldNames[CcShowPeer::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbUrl', 'DbGenre', 'DbDescription', 'DbColor', 'DbBackgroundColor', 'DbLiveStreamUsingAirtimeAuth', 'DbLiveStreamUsingCustomAuth', 'DbLiveStreamUser', 'DbLiveStreamPass', 'DbLinked', 'DbIsLinkable', 'DbImagePath', 'DbHasAutoPlaylist', 'DbAutoPlaylistId', 'DbAutoPlaylistRepeat', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbUrl', 'dbGenre', 'dbDescription', 'dbColor', 'dbBackgroundColor', 'dbLiveStreamUsingAirtimeAuth', 'dbLiveStreamUsingCustomAuth', 'dbLiveStreamUser', 'dbLiveStreamPass', 'dbLinked', 'dbIsLinkable', 'dbImagePath', 'dbHasAutoPlaylist', 'dbAutoPlaylistId', 'dbAutoPlaylistRepeat', ),
BasePeer::TYPE_COLNAME => array (CcShowPeer::ID, CcShowPeer::NAME, CcShowPeer::URL, CcShowPeer::GENRE, CcShowPeer::DESCRIPTION, CcShowPeer::COLOR, CcShowPeer::BACKGROUND_COLOR, CcShowPeer::LIVE_STREAM_USING_AIRTIME_AUTH, CcShowPeer::LIVE_STREAM_USING_CUSTOM_AUTH, CcShowPeer::LIVE_STREAM_USER, CcShowPeer::LIVE_STREAM_PASS, CcShowPeer::LINKED, CcShowPeer::IS_LINKABLE, CcShowPeer::IMAGE_PATH, CcShowPeer::HAS_AUTOPLAYLIST, CcShowPeer::AUTOPLAYLIST_ID, CcShowPeer::AUTOPLAYLIST_REPEAT, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'URL', 'GENRE', 'DESCRIPTION', 'COLOR', 'BACKGROUND_COLOR', 'LIVE_STREAM_USING_AIRTIME_AUTH', 'LIVE_STREAM_USING_CUSTOM_AUTH', 'LIVE_STREAM_USER', 'LIVE_STREAM_PASS', 'LINKED', 'IS_LINKABLE', 'IMAGE_PATH', 'HAS_AUTOPLAYLIST', 'AUTOPLAYLIST_ID', 'AUTOPLAYLIST_REPEAT', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'url', 'genre', 'description', 'color', 'background_color', 'live_stream_using_airtime_auth', 'live_stream_using_custom_auth', 'live_stream_user', 'live_stream_pass', 'linked', 'is_linkable', 'image_path', 'has_autoplaylist', 'autoplaylist_id', 'autoplaylist_repeat', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, )
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbUrl', 'DbGenre', 'DbDescription', 'DbColor', 'DbBackgroundColor', 'DbLiveStreamUsingAirtimeAuth', 'DbLiveStreamUsingCustomAuth', 'DbLiveStreamUser', 'DbLiveStreamPass', 'DbLinked', 'DbIsLinkable', 'DbImagePath', 'DbHasAutoPlaylist', 'DbAutoPlaylistId', 'DbAutoPlaylistRepeat', 'DbOverrideIntroPlaylist', 'DbIntroPlaylistId', 'DbOverrideOutroPlaylist', 'DbOutroPlaylistId', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbUrl', 'dbGenre', 'dbDescription', 'dbColor', 'dbBackgroundColor', 'dbLiveStreamUsingAirtimeAuth', 'dbLiveStreamUsingCustomAuth', 'dbLiveStreamUser', 'dbLiveStreamPass', 'dbLinked', 'dbIsLinkable', 'dbImagePath', 'dbHasAutoPlaylist', 'dbAutoPlaylistId', 'dbAutoPlaylistRepeat', 'dbOverrideIntroPlaylist', 'dbIntroPlaylistId', 'dbOverrideOutroPlaylist', 'dbOutroPlaylistId', ),
BasePeer::TYPE_COLNAME => array (CcShowPeer::ID, CcShowPeer::NAME, CcShowPeer::URL, CcShowPeer::GENRE, CcShowPeer::DESCRIPTION, CcShowPeer::COLOR, CcShowPeer::BACKGROUND_COLOR, CcShowPeer::LIVE_STREAM_USING_AIRTIME_AUTH, CcShowPeer::LIVE_STREAM_USING_CUSTOM_AUTH, CcShowPeer::LIVE_STREAM_USER, CcShowPeer::LIVE_STREAM_PASS, CcShowPeer::LINKED, CcShowPeer::IS_LINKABLE, CcShowPeer::IMAGE_PATH, CcShowPeer::HAS_AUTOPLAYLIST, CcShowPeer::AUTOPLAYLIST_ID, CcShowPeer::AUTOPLAYLIST_REPEAT, CcShowPeer::OVERRIDE_INTRO_PLAYLIST, CcShowPeer::INTRO_PLAYLIST_ID, CcShowPeer::OVERRIDE_OUTRO_PLAYLIST, CcShowPeer::OUTRO_PLAYLIST_ID, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'URL', 'GENRE', 'DESCRIPTION', 'COLOR', 'BACKGROUND_COLOR', 'LIVE_STREAM_USING_AIRTIME_AUTH', 'LIVE_STREAM_USING_CUSTOM_AUTH', 'LIVE_STREAM_USER', 'LIVE_STREAM_PASS', 'LINKED', 'IS_LINKABLE', 'IMAGE_PATH', 'HAS_AUTOPLAYLIST', 'AUTOPLAYLIST_ID', 'AUTOPLAYLIST_REPEAT', 'OVERRIDE_INTRO_PLAYLIST', 'INTRO_PLAYLIST_ID', 'OVERRIDE_OUTRO_PLAYLIST', 'OUTRO_PLAYLIST_ID', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'url', 'genre', 'description', 'color', 'background_color', 'live_stream_using_airtime_auth', 'live_stream_using_custom_auth', 'live_stream_user', 'live_stream_pass', 'linked', 'is_linkable', 'image_path', 'has_autoplaylist', 'autoplaylist_id', 'autoplaylist_repeat', 'override_intro_playlist', 'intro_playlist_id', 'override_outro_playlist', 'outro_playlist_id', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, )
);
/**
@ -117,12 +129,12 @@ abstract class BaseCcShowPeer
* e.g. CcShowPeer::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbUrl' => 2, 'DbGenre' => 3, 'DbDescription' => 4, 'DbColor' => 5, 'DbBackgroundColor' => 6, 'DbLiveStreamUsingAirtimeAuth' => 7, 'DbLiveStreamUsingCustomAuth' => 8, 'DbLiveStreamUser' => 9, 'DbLiveStreamPass' => 10, 'DbLinked' => 11, 'DbIsLinkable' => 12, 'DbImagePath' => 13, 'DbHasAutoPlaylist' => 14, 'DbAutoPlaylistId' => 15, 'DbAutoPlaylistRepeat' => 16, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbUrl' => 2, 'dbGenre' => 3, 'dbDescription' => 4, 'dbColor' => 5, 'dbBackgroundColor' => 6, 'dbLiveStreamUsingAirtimeAuth' => 7, 'dbLiveStreamUsingCustomAuth' => 8, 'dbLiveStreamUser' => 9, 'dbLiveStreamPass' => 10, 'dbLinked' => 11, 'dbIsLinkable' => 12, 'dbImagePath' => 13, 'dbHasAutoPlaylist' => 14, 'dbAutoPlaylistId' => 15, 'dbAutoPlaylistRepeat' => 16, ),
BasePeer::TYPE_COLNAME => array (CcShowPeer::ID => 0, CcShowPeer::NAME => 1, CcShowPeer::URL => 2, CcShowPeer::GENRE => 3, CcShowPeer::DESCRIPTION => 4, CcShowPeer::COLOR => 5, CcShowPeer::BACKGROUND_COLOR => 6, CcShowPeer::LIVE_STREAM_USING_AIRTIME_AUTH => 7, CcShowPeer::LIVE_STREAM_USING_CUSTOM_AUTH => 8, CcShowPeer::LIVE_STREAM_USER => 9, CcShowPeer::LIVE_STREAM_PASS => 10, CcShowPeer::LINKED => 11, CcShowPeer::IS_LINKABLE => 12, CcShowPeer::IMAGE_PATH => 13, CcShowPeer::HAS_AUTOPLAYLIST => 14, CcShowPeer::AUTOPLAYLIST_ID => 15, CcShowPeer::AUTOPLAYLIST_REPEAT => 16, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'URL' => 2, 'GENRE' => 3, 'DESCRIPTION' => 4, 'COLOR' => 5, 'BACKGROUND_COLOR' => 6, 'LIVE_STREAM_USING_AIRTIME_AUTH' => 7, 'LIVE_STREAM_USING_CUSTOM_AUTH' => 8, 'LIVE_STREAM_USER' => 9, 'LIVE_STREAM_PASS' => 10, 'LINKED' => 11, 'IS_LINKABLE' => 12, 'IMAGE_PATH' => 13, 'HAS_AUTOPLAYLIST' => 14, 'AUTOPLAYLIST_ID' => 15, 'AUTOPLAYLIST_REPEAT' => 16, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'url' => 2, 'genre' => 3, 'description' => 4, 'color' => 5, 'background_color' => 6, 'live_stream_using_airtime_auth' => 7, 'live_stream_using_custom_auth' => 8, 'live_stream_user' => 9, 'live_stream_pass' => 10, 'linked' => 11, 'is_linkable' => 12, 'image_path' => 13, 'has_autoplaylist' => 14, 'autoplaylist_id' => 15, 'autoplaylist_repeat' => 16, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, )
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbUrl' => 2, 'DbGenre' => 3, 'DbDescription' => 4, 'DbColor' => 5, 'DbBackgroundColor' => 6, 'DbLiveStreamUsingAirtimeAuth' => 7, 'DbLiveStreamUsingCustomAuth' => 8, 'DbLiveStreamUser' => 9, 'DbLiveStreamPass' => 10, 'DbLinked' => 11, 'DbIsLinkable' => 12, 'DbImagePath' => 13, 'DbHasAutoPlaylist' => 14, 'DbAutoPlaylistId' => 15, 'DbAutoPlaylistRepeat' => 16, 'DbOverrideIntroPlaylist' => 17, 'DbIntroPlaylistId' => 18, 'DbOverrideOutroPlaylist' => 19, 'DbOutroPlaylistId' => 20, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbUrl' => 2, 'dbGenre' => 3, 'dbDescription' => 4, 'dbColor' => 5, 'dbBackgroundColor' => 6, 'dbLiveStreamUsingAirtimeAuth' => 7, 'dbLiveStreamUsingCustomAuth' => 8, 'dbLiveStreamUser' => 9, 'dbLiveStreamPass' => 10, 'dbLinked' => 11, 'dbIsLinkable' => 12, 'dbImagePath' => 13, 'dbHasAutoPlaylist' => 14, 'dbAutoPlaylistId' => 15, 'dbAutoPlaylistRepeat' => 16, 'dbOverrideIntroPlaylist' => 17, 'dbIntroPlaylistId' => 18, 'dbOverrideOutroPlaylist' => 19, 'dbOutroPlaylistId' => 20, ),
BasePeer::TYPE_COLNAME => array (CcShowPeer::ID => 0, CcShowPeer::NAME => 1, CcShowPeer::URL => 2, CcShowPeer::GENRE => 3, CcShowPeer::DESCRIPTION => 4, CcShowPeer::COLOR => 5, CcShowPeer::BACKGROUND_COLOR => 6, CcShowPeer::LIVE_STREAM_USING_AIRTIME_AUTH => 7, CcShowPeer::LIVE_STREAM_USING_CUSTOM_AUTH => 8, CcShowPeer::LIVE_STREAM_USER => 9, CcShowPeer::LIVE_STREAM_PASS => 10, CcShowPeer::LINKED => 11, CcShowPeer::IS_LINKABLE => 12, CcShowPeer::IMAGE_PATH => 13, CcShowPeer::HAS_AUTOPLAYLIST => 14, CcShowPeer::AUTOPLAYLIST_ID => 15, CcShowPeer::AUTOPLAYLIST_REPEAT => 16, CcShowPeer::OVERRIDE_INTRO_PLAYLIST => 17, CcShowPeer::INTRO_PLAYLIST_ID => 18, CcShowPeer::OVERRIDE_OUTRO_PLAYLIST => 19, CcShowPeer::OUTRO_PLAYLIST_ID => 20, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'URL' => 2, 'GENRE' => 3, 'DESCRIPTION' => 4, 'COLOR' => 5, 'BACKGROUND_COLOR' => 6, 'LIVE_STREAM_USING_AIRTIME_AUTH' => 7, 'LIVE_STREAM_USING_CUSTOM_AUTH' => 8, 'LIVE_STREAM_USER' => 9, 'LIVE_STREAM_PASS' => 10, 'LINKED' => 11, 'IS_LINKABLE' => 12, 'IMAGE_PATH' => 13, 'HAS_AUTOPLAYLIST' => 14, 'AUTOPLAYLIST_ID' => 15, 'AUTOPLAYLIST_REPEAT' => 16, 'OVERRIDE_INTRO_PLAYLIST' => 17, 'INTRO_PLAYLIST_ID' => 18, 'OVERRIDE_OUTRO_PLAYLIST' => 19, 'OUTRO_PLAYLIST_ID' => 20, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'url' => 2, 'genre' => 3, 'description' => 4, 'color' => 5, 'background_color' => 6, 'live_stream_using_airtime_auth' => 7, 'live_stream_using_custom_auth' => 8, 'live_stream_user' => 9, 'live_stream_pass' => 10, 'linked' => 11, 'is_linkable' => 12, 'image_path' => 13, 'has_autoplaylist' => 14, 'autoplaylist_id' => 15, 'autoplaylist_repeat' => 16, 'override_intro_playlist' => 17, 'intro_playlist_id' => 18, 'override_outro_playlist' => 19, 'outro_playlist_id' => 20, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, )
);
/**
@ -213,6 +225,10 @@ abstract class BaseCcShowPeer
$criteria->addSelectColumn(CcShowPeer::HAS_AUTOPLAYLIST);
$criteria->addSelectColumn(CcShowPeer::AUTOPLAYLIST_ID);
$criteria->addSelectColumn(CcShowPeer::AUTOPLAYLIST_REPEAT);
$criteria->addSelectColumn(CcShowPeer::OVERRIDE_INTRO_PLAYLIST);
$criteria->addSelectColumn(CcShowPeer::INTRO_PLAYLIST_ID);
$criteria->addSelectColumn(CcShowPeer::OVERRIDE_OUTRO_PLAYLIST);
$criteria->addSelectColumn(CcShowPeer::OUTRO_PLAYLIST_ID);
} else {
$criteria->addSelectColumn($alias . '.id');
$criteria->addSelectColumn($alias . '.name');
@ -231,6 +247,10 @@ abstract class BaseCcShowPeer
$criteria->addSelectColumn($alias . '.has_autoplaylist');
$criteria->addSelectColumn($alias . '.autoplaylist_id');
$criteria->addSelectColumn($alias . '.autoplaylist_repeat');
$criteria->addSelectColumn($alias . '.override_intro_playlist');
$criteria->addSelectColumn($alias . '.intro_playlist_id');
$criteria->addSelectColumn($alias . '.override_outro_playlist');
$criteria->addSelectColumn($alias . '.outro_playlist_id');
}
}
@ -545,7 +565,7 @@ abstract class BaseCcShowPeer
/**
* Returns the number of rows matching criteria, joining the related CcPlaylist table
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbAutoPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
@ -553,7 +573,7 @@ abstract class BaseCcShowPeer
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinCcPlaylist(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
public static function doCountJoinCcPlaylistRelatedByDbAutoPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
@ -595,6 +615,108 @@ abstract class BaseCcShowPeer
}
/**
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbIntroPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinCcPlaylistRelatedByDbIntroPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcShowPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcShowPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria->addJoin(CcShowPeer::INTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbOutroPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinCcPlaylistRelatedByDbOutroPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcShowPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcShowPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria->addJoin(CcShowPeer::OUTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Selects a collection of CcShow objects pre-filled with their CcPlaylist objects.
* @param Criteria $criteria
@ -604,7 +726,7 @@ abstract class BaseCcShowPeer
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinCcPlaylist(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
public static function doSelectJoinCcPlaylistRelatedByDbAutoPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
@ -650,7 +772,141 @@ abstract class BaseCcShowPeer
} // if obj2 already loaded
// Add the $obj1 (CcShow) to $obj2 (CcPlaylist)
$obj2->addCcShow($obj1);
$obj2->addCcShowRelatedByDbAutoPlaylistId($obj1);
} // if joined row was not null
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Selects a collection of CcShow objects pre-filled with their CcPlaylist objects.
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcShow objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinCcPlaylistRelatedByDbIntroPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
}
CcShowPeer::addSelectColumns($criteria);
$startcol = CcShowPeer::NUM_HYDRATE_COLUMNS;
CcPlaylistPeer::addSelectColumns($criteria);
$criteria->addJoin(CcShowPeer::INTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcShowPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcShowPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcShowPeer::getOMClass();
$obj1 = new $cls();
$obj1->hydrate($row);
CcShowPeer::addInstanceToPool($obj1, $key1);
} // if $obj1 already loaded
$key2 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol);
if ($key2 !== null) {
$obj2 = CcPlaylistPeer::getInstanceFromPool($key2);
if (!$obj2) {
$cls = CcPlaylistPeer::getOMClass();
$obj2 = new $cls();
$obj2->hydrate($row, $startcol);
CcPlaylistPeer::addInstanceToPool($obj2, $key2);
} // if obj2 already loaded
// Add the $obj1 (CcShow) to $obj2 (CcPlaylist)
$obj2->addCcShowRelatedByDbIntroPlaylistId($obj1);
} // if joined row was not null
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Selects a collection of CcShow objects pre-filled with their CcPlaylist objects.
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcShow objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinCcPlaylistRelatedByDbOutroPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
}
CcShowPeer::addSelectColumns($criteria);
$startcol = CcShowPeer::NUM_HYDRATE_COLUMNS;
CcPlaylistPeer::addSelectColumns($criteria);
$criteria->addJoin(CcShowPeer::OUTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcShowPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcShowPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcShowPeer::getOMClass();
$obj1 = new $cls();
$obj1->hydrate($row);
CcShowPeer::addInstanceToPool($obj1, $key1);
} // if $obj1 already loaded
$key2 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol);
if ($key2 !== null) {
$obj2 = CcPlaylistPeer::getInstanceFromPool($key2);
if (!$obj2) {
$cls = CcPlaylistPeer::getOMClass();
$obj2 = new $cls();
$obj2->hydrate($row, $startcol);
CcPlaylistPeer::addInstanceToPool($obj2, $key2);
} // if obj2 already loaded
// Add the $obj1 (CcShow) to $obj2 (CcPlaylist)
$obj2->addCcShowRelatedByDbOutroPlaylistId($obj1);
} // if joined row was not null
@ -700,6 +956,10 @@ abstract class BaseCcShowPeer
$criteria->addJoin(CcShowPeer::AUTOPLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$criteria->addJoin(CcShowPeer::INTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$criteria->addJoin(CcShowPeer::OUTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
@ -737,8 +997,18 @@ abstract class BaseCcShowPeer
CcPlaylistPeer::addSelectColumns($criteria);
$startcol3 = $startcol2 + CcPlaylistPeer::NUM_HYDRATE_COLUMNS;
CcPlaylistPeer::addSelectColumns($criteria);
$startcol4 = $startcol3 + CcPlaylistPeer::NUM_HYDRATE_COLUMNS;
CcPlaylistPeer::addSelectColumns($criteria);
$startcol5 = $startcol4 + CcPlaylistPeer::NUM_HYDRATE_COLUMNS;
$criteria->addJoin(CcShowPeer::AUTOPLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$criteria->addJoin(CcShowPeer::INTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$criteria->addJoin(CcShowPeer::OUTRO_PLAYLIST_ID, CcPlaylistPeer::ID, $join_behavior);
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
@ -771,9 +1041,342 @@ abstract class BaseCcShowPeer
} // if obj2 loaded
// Add the $obj1 (CcShow) to the collection in $obj2 (CcPlaylist)
$obj2->addCcShow($obj1);
$obj2->addCcShowRelatedByDbAutoPlaylistId($obj1);
} // if joined row not null
// Add objects for joined CcPlaylist rows
$key3 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol3);
if ($key3 !== null) {
$obj3 = CcPlaylistPeer::getInstanceFromPool($key3);
if (!$obj3) {
$cls = CcPlaylistPeer::getOMClass();
$obj3 = new $cls();
$obj3->hydrate($row, $startcol3);
CcPlaylistPeer::addInstanceToPool($obj3, $key3);
} // if obj3 loaded
// Add the $obj1 (CcShow) to the collection in $obj3 (CcPlaylist)
$obj3->addCcShowRelatedByDbIntroPlaylistId($obj1);
} // if joined row not null
// Add objects for joined CcPlaylist rows
$key4 = CcPlaylistPeer::getPrimaryKeyHashFromRow($row, $startcol4);
if ($key4 !== null) {
$obj4 = CcPlaylistPeer::getInstanceFromPool($key4);
if (!$obj4) {
$cls = CcPlaylistPeer::getOMClass();
$obj4 = new $cls();
$obj4->hydrate($row, $startcol4);
CcPlaylistPeer::addInstanceToPool($obj4, $key4);
} // if obj4 loaded
// Add the $obj1 (CcShow) to the collection in $obj4 (CcPlaylist)
$obj4->addCcShowRelatedByDbOutroPlaylistId($obj1);
} // if joined row not null
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbAutoPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinAllExceptCcPlaylistRelatedByDbAutoPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcShowPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcShowPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY should not affect count
// Set the correct dbName
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbIntroPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinAllExceptCcPlaylistRelatedByDbIntroPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcShowPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcShowPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY should not affect count
// Set the correct dbName
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Returns the number of rows matching criteria, joining the related CcPlaylistRelatedByDbOutroPlaylistId table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinAllExceptCcPlaylistRelatedByDbOutroPlaylistId(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcShowPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcShowPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY should not affect count
// Set the correct dbName
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Selects a collection of CcShow objects pre-filled with all related objects except CcPlaylistRelatedByDbAutoPlaylistId.
*
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcShow objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAllExceptCcPlaylistRelatedByDbAutoPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
// $criteria->getDbName() will return the same object if not set to another value
// so == check is okay and faster
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
}
CcShowPeer::addSelectColumns($criteria);
$startcol2 = CcShowPeer::NUM_HYDRATE_COLUMNS;
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcShowPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcShowPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcShowPeer::getOMClass();
$obj1 = new $cls();
$obj1->hydrate($row);
CcShowPeer::addInstanceToPool($obj1, $key1);
} // if obj1 already loaded
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Selects a collection of CcShow objects pre-filled with all related objects except CcPlaylistRelatedByDbIntroPlaylistId.
*
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcShow objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAllExceptCcPlaylistRelatedByDbIntroPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
// $criteria->getDbName() will return the same object if not set to another value
// so == check is okay and faster
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
}
CcShowPeer::addSelectColumns($criteria);
$startcol2 = CcShowPeer::NUM_HYDRATE_COLUMNS;
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcShowPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcShowPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcShowPeer::getOMClass();
$obj1 = new $cls();
$obj1->hydrate($row);
CcShowPeer::addInstanceToPool($obj1, $key1);
} // if obj1 already loaded
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Selects a collection of CcShow objects pre-filled with all related objects except CcPlaylistRelatedByDbOutroPlaylistId.
*
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcShow objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAllExceptCcPlaylistRelatedByDbOutroPlaylistId(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
// $criteria->getDbName() will return the same object if not set to another value
// so == check is okay and faster
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(CcShowPeer::DATABASE_NAME);
}
CcShowPeer::addSelectColumns($criteria);
$startcol2 = CcShowPeer::NUM_HYDRATE_COLUMNS;
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcShowPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcShowPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcShowPeer::getOMClass();
$obj1 = new $cls();
$obj1->hydrate($row);
CcShowPeer::addInstanceToPool($obj1, $key1);
} // if obj1 already loaded
$results[] = $obj1;
}
$stmt->closeCursor();

View File

@ -23,6 +23,10 @@
* @method CcShowQuery orderByDbHasAutoPlaylist($order = Criteria::ASC) Order by the has_autoplaylist column
* @method CcShowQuery orderByDbAutoPlaylistId($order = Criteria::ASC) Order by the autoplaylist_id column
* @method CcShowQuery orderByDbAutoPlaylistRepeat($order = Criteria::ASC) Order by the autoplaylist_repeat column
* @method CcShowQuery orderByDbOverrideIntroPlaylist($order = Criteria::ASC) Order by the override_intro_playlist column
* @method CcShowQuery orderByDbIntroPlaylistId($order = Criteria::ASC) Order by the intro_playlist_id column
* @method CcShowQuery orderByDbOverrideOutroPlaylist($order = Criteria::ASC) Order by the override_outro_playlist column
* @method CcShowQuery orderByDbOutroPlaylistId($order = Criteria::ASC) Order by the outro_playlist_id column
*
* @method CcShowQuery groupByDbId() Group by the id column
* @method CcShowQuery groupByDbName() Group by the name column
@ -41,14 +45,26 @@
* @method CcShowQuery groupByDbHasAutoPlaylist() Group by the has_autoplaylist column
* @method CcShowQuery groupByDbAutoPlaylistId() Group by the autoplaylist_id column
* @method CcShowQuery groupByDbAutoPlaylistRepeat() Group by the autoplaylist_repeat column
* @method CcShowQuery groupByDbOverrideIntroPlaylist() Group by the override_intro_playlist column
* @method CcShowQuery groupByDbIntroPlaylistId() Group by the intro_playlist_id column
* @method CcShowQuery groupByDbOverrideOutroPlaylist() Group by the override_outro_playlist column
* @method CcShowQuery groupByDbOutroPlaylistId() Group by the outro_playlist_id column
*
* @method CcShowQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method CcShowQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
* @method CcShowQuery innerJoin($relation) Adds a INNER JOIN clause to the query
*
* @method CcShowQuery leftJoinCcPlaylist($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcPlaylist relation
* @method CcShowQuery rightJoinCcPlaylist($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcPlaylist relation
* @method CcShowQuery innerJoinCcPlaylist($relationAlias = null) Adds a INNER JOIN clause to the query using the CcPlaylist relation
* @method CcShowQuery leftJoinCcPlaylistRelatedByDbAutoPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcPlaylistRelatedByDbAutoPlaylistId relation
* @method CcShowQuery rightJoinCcPlaylistRelatedByDbAutoPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcPlaylistRelatedByDbAutoPlaylistId relation
* @method CcShowQuery innerJoinCcPlaylistRelatedByDbAutoPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcPlaylistRelatedByDbAutoPlaylistId relation
*
* @method CcShowQuery leftJoinCcPlaylistRelatedByDbIntroPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcPlaylistRelatedByDbIntroPlaylistId relation
* @method CcShowQuery rightJoinCcPlaylistRelatedByDbIntroPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcPlaylistRelatedByDbIntroPlaylistId relation
* @method CcShowQuery innerJoinCcPlaylistRelatedByDbIntroPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcPlaylistRelatedByDbIntroPlaylistId relation
*
* @method CcShowQuery leftJoinCcPlaylistRelatedByDbOutroPlaylistId($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcPlaylistRelatedByDbOutroPlaylistId relation
* @method CcShowQuery rightJoinCcPlaylistRelatedByDbOutroPlaylistId($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcPlaylistRelatedByDbOutroPlaylistId relation
* @method CcShowQuery innerJoinCcPlaylistRelatedByDbOutroPlaylistId($relationAlias = null) Adds a INNER JOIN clause to the query using the CcPlaylistRelatedByDbOutroPlaylistId relation
*
* @method CcShowQuery leftJoinCcShowInstances($relationAlias = null) Adds a LEFT JOIN clause to the query using the CcShowInstances relation
* @method CcShowQuery rightJoinCcShowInstances($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CcShowInstances relation
@ -85,6 +101,10 @@
* @method CcShow findOneByDbHasAutoPlaylist(boolean $has_autoplaylist) Return the first CcShow filtered by the has_autoplaylist column
* @method CcShow findOneByDbAutoPlaylistId(int $autoplaylist_id) Return the first CcShow filtered by the autoplaylist_id column
* @method CcShow findOneByDbAutoPlaylistRepeat(boolean $autoplaylist_repeat) Return the first CcShow filtered by the autoplaylist_repeat column
* @method CcShow findOneByDbOverrideIntroPlaylist(boolean $override_intro_playlist) Return the first CcShow filtered by the override_intro_playlist column
* @method CcShow findOneByDbIntroPlaylistId(int $intro_playlist_id) Return the first CcShow filtered by the intro_playlist_id column
* @method CcShow findOneByDbOverrideOutroPlaylist(boolean $override_outro_playlist) Return the first CcShow filtered by the override_outro_playlist column
* @method CcShow findOneByDbOutroPlaylistId(int $outro_playlist_id) Return the first CcShow filtered by the outro_playlist_id column
*
* @method array findByDbId(int $id) Return CcShow objects filtered by the id column
* @method array findByDbName(string $name) Return CcShow objects filtered by the name column
@ -103,6 +123,10 @@
* @method array findByDbHasAutoPlaylist(boolean $has_autoplaylist) Return CcShow objects filtered by the has_autoplaylist column
* @method array findByDbAutoPlaylistId(int $autoplaylist_id) Return CcShow objects filtered by the autoplaylist_id column
* @method array findByDbAutoPlaylistRepeat(boolean $autoplaylist_repeat) Return CcShow objects filtered by the autoplaylist_repeat column
* @method array findByDbOverrideIntroPlaylist(boolean $override_intro_playlist) Return CcShow objects filtered by the override_intro_playlist column
* @method array findByDbIntroPlaylistId(int $intro_playlist_id) Return CcShow objects filtered by the intro_playlist_id column
* @method array findByDbOverrideOutroPlaylist(boolean $override_outro_playlist) Return CcShow objects filtered by the override_outro_playlist column
* @method array findByDbOutroPlaylistId(int $outro_playlist_id) Return CcShow objects filtered by the outro_playlist_id column
*
* @package propel.generator.airtime.om
*/
@ -210,7 +234,7 @@ abstract class BaseCcShowQuery extends ModelCriteria
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT "id", "name", "url", "genre", "description", "color", "background_color", "live_stream_using_airtime_auth", "live_stream_using_custom_auth", "live_stream_user", "live_stream_pass", "linked", "is_linkable", "image_path", "has_autoplaylist", "autoplaylist_id", "autoplaylist_repeat" FROM "cc_show" WHERE "id" = :p0';
$sql = 'SELECT "id", "name", "url", "genre", "description", "color", "background_color", "live_stream_using_airtime_auth", "live_stream_using_custom_auth", "live_stream_user", "live_stream_pass", "linked", "is_linkable", "image_path", "has_autoplaylist", "autoplaylist_id", "autoplaylist_repeat", "override_intro_playlist", "intro_playlist_id", "override_outro_playlist", "outro_playlist_id" FROM "cc_show" WHERE "id" = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
@ -748,7 +772,7 @@ abstract class BaseCcShowQuery extends ModelCriteria
* $query->filterByDbAutoPlaylistId(array('max' => 12)); // WHERE autoplaylist_id <= 12
* </code>
*
* @see filterByCcPlaylist()
* @see filterByCcPlaylistRelatedByDbAutoPlaylistId()
*
* @param mixed $dbAutoPlaylistId The value to use as filter.
* Use scalar values for equality.
@ -808,6 +832,148 @@ abstract class BaseCcShowQuery extends ModelCriteria
return $this->addUsingAlias(CcShowPeer::AUTOPLAYLIST_REPEAT, $dbAutoPlaylistRepeat, $comparison);
}
/**
* Filter the query on the override_intro_playlist column
*
* Example usage:
* <code>
* $query->filterByDbOverrideIntroPlaylist(true); // WHERE override_intro_playlist = true
* $query->filterByDbOverrideIntroPlaylist('yes'); // WHERE override_intro_playlist = true
* </code>
*
* @param boolean|string $dbOverrideIntroPlaylist The value to use as filter.
* Non-boolean arguments are converted using the following rules:
* * 1, '1', 'true', 'on', and 'yes' are converted to boolean true
* * 0, '0', 'false', 'off', and 'no' are converted to boolean false
* Check on string values is case insensitive (so 'FaLsE' is seen as 'false').
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
*/
public function filterByDbOverrideIntroPlaylist($dbOverrideIntroPlaylist = null, $comparison = null)
{
if (is_string($dbOverrideIntroPlaylist)) {
$dbOverrideIntroPlaylist = in_array(strtolower($dbOverrideIntroPlaylist), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
}
return $this->addUsingAlias(CcShowPeer::OVERRIDE_INTRO_PLAYLIST, $dbOverrideIntroPlaylist, $comparison);
}
/**
* Filter the query on the intro_playlist_id column
*
* Example usage:
* <code>
* $query->filterByDbIntroPlaylistId(1234); // WHERE intro_playlist_id = 1234
* $query->filterByDbIntroPlaylistId(array(12, 34)); // WHERE intro_playlist_id IN (12, 34)
* $query->filterByDbIntroPlaylistId(array('min' => 12)); // WHERE intro_playlist_id >= 12
* $query->filterByDbIntroPlaylistId(array('max' => 12)); // WHERE intro_playlist_id <= 12
* </code>
*
* @see filterByCcPlaylistRelatedByDbIntroPlaylistId()
*
* @param mixed $dbIntroPlaylistId The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
*/
public function filterByDbIntroPlaylistId($dbIntroPlaylistId = null, $comparison = null)
{
if (is_array($dbIntroPlaylistId)) {
$useMinMax = false;
if (isset($dbIntroPlaylistId['min'])) {
$this->addUsingAlias(CcShowPeer::INTRO_PLAYLIST_ID, $dbIntroPlaylistId['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbIntroPlaylistId['max'])) {
$this->addUsingAlias(CcShowPeer::INTRO_PLAYLIST_ID, $dbIntroPlaylistId['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcShowPeer::INTRO_PLAYLIST_ID, $dbIntroPlaylistId, $comparison);
}
/**
* Filter the query on the override_outro_playlist column
*
* Example usage:
* <code>
* $query->filterByDbOverrideOutroPlaylist(true); // WHERE override_outro_playlist = true
* $query->filterByDbOverrideOutroPlaylist('yes'); // WHERE override_outro_playlist = true
* </code>
*
* @param boolean|string $dbOverrideOutroPlaylist The value to use as filter.
* Non-boolean arguments are converted using the following rules:
* * 1, '1', 'true', 'on', and 'yes' are converted to boolean true
* * 0, '0', 'false', 'off', and 'no' are converted to boolean false
* Check on string values is case insensitive (so 'FaLsE' is seen as 'false').
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
*/
public function filterByDbOverrideOutroPlaylist($dbOverrideOutroPlaylist = null, $comparison = null)
{
if (is_string($dbOverrideOutroPlaylist)) {
$dbOverrideOutroPlaylist = in_array(strtolower($dbOverrideOutroPlaylist), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
}
return $this->addUsingAlias(CcShowPeer::OVERRIDE_OUTRO_PLAYLIST, $dbOverrideOutroPlaylist, $comparison);
}
/**
* Filter the query on the outro_playlist_id column
*
* Example usage:
* <code>
* $query->filterByDbOutroPlaylistId(1234); // WHERE outro_playlist_id = 1234
* $query->filterByDbOutroPlaylistId(array(12, 34)); // WHERE outro_playlist_id IN (12, 34)
* $query->filterByDbOutroPlaylistId(array('min' => 12)); // WHERE outro_playlist_id >= 12
* $query->filterByDbOutroPlaylistId(array('max' => 12)); // WHERE outro_playlist_id <= 12
* </code>
*
* @see filterByCcPlaylistRelatedByDbOutroPlaylistId()
*
* @param mixed $dbOutroPlaylistId The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
*/
public function filterByDbOutroPlaylistId($dbOutroPlaylistId = null, $comparison = null)
{
if (is_array($dbOutroPlaylistId)) {
$useMinMax = false;
if (isset($dbOutroPlaylistId['min'])) {
$this->addUsingAlias(CcShowPeer::OUTRO_PLAYLIST_ID, $dbOutroPlaylistId['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbOutroPlaylistId['max'])) {
$this->addUsingAlias(CcShowPeer::OUTRO_PLAYLIST_ID, $dbOutroPlaylistId['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcShowPeer::OUTRO_PLAYLIST_ID, $dbOutroPlaylistId, $comparison);
}
/**
* Filter the query by a related CcPlaylist object
*
@ -817,7 +983,7 @@ abstract class BaseCcShowQuery extends ModelCriteria
* @return CcShowQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcPlaylist($ccPlaylist, $comparison = null)
public function filterByCcPlaylistRelatedByDbAutoPlaylistId($ccPlaylist, $comparison = null)
{
if ($ccPlaylist instanceof CcPlaylist) {
return $this
@ -830,22 +996,22 @@ abstract class BaseCcShowQuery extends ModelCriteria
return $this
->addUsingAlias(CcShowPeer::AUTOPLAYLIST_ID, $ccPlaylist->toKeyValue('PrimaryKey', 'DbId'), $comparison);
} else {
throw new PropelException('filterByCcPlaylist() only accepts arguments of type CcPlaylist or PropelCollection');
throw new PropelException('filterByCcPlaylistRelatedByDbAutoPlaylistId() only accepts arguments of type CcPlaylist or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcPlaylist relation
* Adds a JOIN clause to the query using the CcPlaylistRelatedByDbAutoPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcShowQuery The current query, for fluid interface
*/
public function joinCcPlaylist($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
public function joinCcPlaylistRelatedByDbAutoPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcPlaylist');
$relationMap = $tableMap->getRelation('CcPlaylistRelatedByDbAutoPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
@ -860,14 +1026,14 @@ abstract class BaseCcShowQuery extends ModelCriteria
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcPlaylist');
$this->addJoinObject($join, 'CcPlaylistRelatedByDbAutoPlaylistId');
}
return $this;
}
/**
* Use the CcPlaylist relation CcPlaylist object
* Use the CcPlaylistRelatedByDbAutoPlaylistId relation CcPlaylist object
*
* @see useQuery()
*
@ -877,11 +1043,163 @@ abstract class BaseCcShowQuery extends ModelCriteria
*
* @return CcPlaylistQuery A secondary query class using the current class as primary query
*/
public function useCcPlaylistQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
public function useCcPlaylistRelatedByDbAutoPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcPlaylist($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcPlaylist', 'CcPlaylistQuery');
->joinCcPlaylistRelatedByDbAutoPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcPlaylistRelatedByDbAutoPlaylistId', 'CcPlaylistQuery');
}
/**
* Filter the query by a related CcPlaylist object
*
* @param CcPlaylist|PropelObjectCollection $ccPlaylist The related object(s) to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcPlaylistRelatedByDbIntroPlaylistId($ccPlaylist, $comparison = null)
{
if ($ccPlaylist instanceof CcPlaylist) {
return $this
->addUsingAlias(CcShowPeer::INTRO_PLAYLIST_ID, $ccPlaylist->getDbId(), $comparison);
} elseif ($ccPlaylist instanceof PropelObjectCollection) {
if (null === $comparison) {
$comparison = Criteria::IN;
}
return $this
->addUsingAlias(CcShowPeer::INTRO_PLAYLIST_ID, $ccPlaylist->toKeyValue('PrimaryKey', 'DbId'), $comparison);
} else {
throw new PropelException('filterByCcPlaylistRelatedByDbIntroPlaylistId() only accepts arguments of type CcPlaylist or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcPlaylistRelatedByDbIntroPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcShowQuery The current query, for fluid interface
*/
public function joinCcPlaylistRelatedByDbIntroPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcPlaylistRelatedByDbIntroPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if ($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcPlaylistRelatedByDbIntroPlaylistId');
}
return $this;
}
/**
* Use the CcPlaylistRelatedByDbIntroPlaylistId relation CcPlaylist object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcPlaylistQuery A secondary query class using the current class as primary query
*/
public function useCcPlaylistRelatedByDbIntroPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcPlaylistRelatedByDbIntroPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcPlaylistRelatedByDbIntroPlaylistId', 'CcPlaylistQuery');
}
/**
* Filter the query by a related CcPlaylist object
*
* @param CcPlaylist|PropelObjectCollection $ccPlaylist The related object(s) to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowQuery The current query, for fluid interface
* @throws PropelException - if the provided filter is invalid.
*/
public function filterByCcPlaylistRelatedByDbOutroPlaylistId($ccPlaylist, $comparison = null)
{
if ($ccPlaylist instanceof CcPlaylist) {
return $this
->addUsingAlias(CcShowPeer::OUTRO_PLAYLIST_ID, $ccPlaylist->getDbId(), $comparison);
} elseif ($ccPlaylist instanceof PropelObjectCollection) {
if (null === $comparison) {
$comparison = Criteria::IN;
}
return $this
->addUsingAlias(CcShowPeer::OUTRO_PLAYLIST_ID, $ccPlaylist->toKeyValue('PrimaryKey', 'DbId'), $comparison);
} else {
throw new PropelException('filterByCcPlaylistRelatedByDbOutroPlaylistId() only accepts arguments of type CcPlaylist or PropelCollection');
}
}
/**
* Adds a JOIN clause to the query using the CcPlaylistRelatedByDbOutroPlaylistId relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcShowQuery The current query, for fluid interface
*/
public function joinCcPlaylistRelatedByDbOutroPlaylistId($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcPlaylistRelatedByDbOutroPlaylistId');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if ($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcPlaylistRelatedByDbOutroPlaylistId');
}
return $this;
}
/**
* Use the CcPlaylistRelatedByDbOutroPlaylistId relation CcPlaylist object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcPlaylistQuery A secondary query class using the current class as primary query
*/
public function useCcPlaylistRelatedByDbOutroPlaylistIdQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN)
{
return $this
->joinCcPlaylistRelatedByDbOutroPlaylistId($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcPlaylistRelatedByDbOutroPlaylistId', 'CcPlaylistQuery');
}
/**

View File

@ -164,6 +164,8 @@ class Application_Service_ShowFormService
'add_show_has_autoplaylist' => $this->ccShow->getDbHasAutoPlaylist() ? 1 : 0,
'add_show_autoplaylist_id' => $this->ccShow->getDbAutoPlaylistId(),
'add_show_autoplaylist_repeat' => $this->ccShow->getDbAutoPlaylistRepeat(),
'add_show_intro_playlist_id' => $this->ccShow->getDbOverrideIntroPlaylist() ? $this->ccShow->getDbIntroPlaylistId() : 0,
'add_show_outro_playlist_id' => $this->ccShow->getDbOverrideOutroPlaylist() ? $this->ccShow->getDbOutroPlaylistId() : 0,
]
);
}

View File

@ -1668,6 +1668,16 @@ SQL;
$ccShow->setDbAutoPlaylistId($showData['add_show_autoplaylist_id']);
}
$ccShow->setDbOverrideIntroPlaylist($showData['add_show_intro_playlist_id'] != 0);
if ($showData['add_show_intro_playlist_id'] != '') {
$ccShow->setDbIntroPlaylistId($showData['add_show_intro_playlist_id']);
}
$ccShow->setDbOverrideOutroPlaylist($showData['add_show_outro_playlist_id'] != 0);
if ($showData['add_show_outro_playlist_id'] != '') {
$ccShow->setDbOutroPlaylistId($showData['add_show_outro_playlist_id']);
}
// Here a user has edited a show and linked it.
// We need to grab the existing show instances ids and fill their content
// with the content from the show instance that was clicked on to edit the show.

View File

@ -19,6 +19,7 @@
</dt>
<dd>
<?php echo $this->element->getElement('add_show_autoplaylist_id') ?>
</dd>
</div>
<div id="add_show_autoplaylist_repeat">
<dt id="add_show_autoplaylist_repeat_label">
@ -30,7 +31,26 @@
<?php echo $this->element->getElement('add_show_autoplaylist_repeat') ?>
</dd>
</div>
<hr/>
<div id="add_show_override_intro_playlist_dropdown">
<dt id="add_show_intro_playlist_id">
<label for="add_show_intro_playlist_id" class="required">
<?php echo $this->element->getElement('add_show_intro_playlist_id')->getLabel() ?>
</label>
</dt>
<dd>
<?php echo $this->element->getElement('add_show_intro_playlist_id') ?>
</dd>
</div>
<div id="add_show_override_outro_playlist_dropdown">
<dt id="add_show_outro_playlist_id">
<label for="add_show_outro_playlist_id" class="required">
<?php echo $this->element->getElement('add_show_outro_playlist_id')->getLabel() ?>
</label>
</dt>
<dd>
<?php echo $this->element->getElement('add_show_outro_playlist_id') ?>
</dd>
</div>
</dl>
</fieldset>

View File

@ -18,6 +18,7 @@ $baseUrl = Config::getBasePath();
<div class="inner_track_editor_title" style="width: 100%;">
<h2 style="line-height: 26px !important;"><span class="title_obj_name"><?php echo ($this->title); ?></span></h2>
<h3 style="line-height: 2px !important;"><span class=""><?php echo ($this->artist_name); ?></span></h3>
<h5 style="line-height: 26px !important;"><span class=""><?php echo ($this->file_name) . " (" . $this->file_size . ")"; ?></span></h5>
</div>
</div>
</div>

View File

@ -122,9 +122,19 @@
<column name="has_autoplaylist" phpName="DbHasAutoPlaylist" type="BOOLEAN" required="true" defaultValue="false" />
<column name="autoplaylist_id" phpName="DbAutoPlaylistId" type="INTEGER" required="false" />
<column name="autoplaylist_repeat" phpName="DbAutoPlaylistRepeat" type="BOOLEAN" required="true" defaultValue="false" />
<column name="override_intro_playlist" phpName="DbOverrideIntroPlaylist" type="BOOLEAN" required="true" defaultValue="false" />
<column name="intro_playlist_id" phpName="DbIntroPlaylistId" type="INTEGER" required="false" />
<column name="override_outro_playlist" phpName="DbOverrideOutroPlaylist" type="BOOLEAN" required="true" defaultValue="false" />
<column name="outro_playlist_id" phpName="DbOutroPlaylistId" type="INTEGER" required="false" />
<foreign-key foreignTable="cc_playlist" name="cc_playlist_autoplaylist_fkey" onDelete="SETNULL">
<reference local="autoplaylist_id" foreign="id" />
</foreign-key>
<foreign-key foreignTable="cc_playlist" name="cc_playlist_intro_playlist_fkey" onDelete="SETNULL">
<reference local="intro_playlist_id" foreign="id" />
</foreign-key>
<foreign-key foreignTable="cc_playlist" name="cc_playlist_outro_playlist_fkey" onDelete="SETNULL">
<reference local="outro_playlist_id" foreign="id" />
</foreign-key>
</table>
<table name="cc_show_instances" phpName="CcShowInstances">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true" />

216
legacy/composer.lock generated
View File

@ -62,24 +62,24 @@
},
{
"name": "composer/semver",
"version": "3.4.0",
"version": "3.4.3",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
"url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.4",
"symfony/phpunit-bridge": "^4.2 || ^5"
"phpstan/phpstan": "^1.11",
"symfony/phpunit-bridge": "^3 || ^7"
},
"type": "library",
"extra": {
@ -123,7 +123,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.0"
"source": "https://github.com/composer/semver/tree/3.4.3"
},
"funding": [
{
@ -139,7 +139,7 @@
"type": "tidelift"
}
],
"time": "2023-08-31T09:50:34+00:00"
"time": "2024-09-19T14:15:21+00:00"
},
{
"name": "james-heinrich/getid3",
@ -760,16 +760,16 @@
},
{
"name": "php-amqplib/php-amqplib",
"version": "v3.6.2",
"version": "v3.7.2",
"source": {
"type": "git",
"url": "https://github.com/php-amqplib/php-amqplib.git",
"reference": "cb514530ce45a6d2f636be5196010c47c3bcf6e0"
"reference": "738a73eb0019b6c99d9bc25d7a0c0dd8f56a5199"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/cb514530ce45a6d2f636be5196010c47c3bcf6e0",
"reference": "cb514530ce45a6d2f636be5196010c47c3bcf6e0",
"url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/738a73eb0019b6c99d9bc25d7a0c0dd8f56a5199",
"reference": "738a73eb0019b6c99d9bc25d7a0c0dd8f56a5199",
"shasum": ""
},
"require": {
@ -835,26 +835,26 @@
],
"support": {
"issues": "https://github.com/php-amqplib/php-amqplib/issues",
"source": "https://github.com/php-amqplib/php-amqplib/tree/v3.6.2"
"source": "https://github.com/php-amqplib/php-amqplib/tree/v3.7.2"
},
"time": "2024-04-15T18:31:22+00:00"
"time": "2024-11-21T09:21:41+00:00"
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.37",
"version": "3.0.42",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8"
"reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db92f1b1987b12b13f248fe76c3a52cadb67bb98",
"reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^1|^2",
"paragonie/constant_time_encoding": "^1|^2|^3",
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
"php": ">=5.6.1"
},
@ -931,7 +931,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.37"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.42"
},
"funding": [
{
@ -947,7 +947,7 @@
"type": "tidelift"
}
],
"time": "2024-03-03T02:14:58+00:00"
"time": "2024-09-16T03:06:04+00:00"
},
{
"name": "psr/http-message",
@ -1004,16 +1004,16 @@
},
{
"name": "simplepie/simplepie",
"version": "1.8.0",
"version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/simplepie/simplepie.git",
"reference": "65b095d87bc00898d8fa7737bdbcda93a3fbcc55"
"reference": "a567b8ab9b6145a23e6a9ec2b6b74f56d52f7ad1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/65b095d87bc00898d8fa7737bdbcda93a3fbcc55",
"reference": "65b095d87bc00898d8fa7737bdbcda93a3fbcc55",
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/a567b8ab9b6145a23e6a9ec2b6b74f56d52f7ad1",
"reference": "a567b8ab9b6145a23e6a9ec2b6b74f56d52f7ad1",
"shasum": ""
},
"require": {
@ -1074,22 +1074,22 @@
],
"support": {
"issues": "https://github.com/simplepie/simplepie/issues",
"source": "https://github.com/simplepie/simplepie/tree/1.8.0"
"source": "https://github.com/simplepie/simplepie/tree/1.8.1"
},
"time": "2023-01-20T08:37:35+00:00"
"time": "2024-11-22T16:33:20+00:00"
},
{
"name": "symfony/config",
"version": "v5.4.40",
"version": "v5.4.46",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "d4e1db78421163b98dd9971d247fd0df4a57ee5e"
"reference": "977c88a02d7d3f16904a81907531b19666a08e78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/d4e1db78421163b98dd9971d247fd0df4a57ee5e",
"reference": "d4e1db78421163b98dd9971d247fd0df4a57ee5e",
"url": "https://api.github.com/repos/symfony/config/zipball/977c88a02d7d3f16904a81907531b19666a08e78",
"reference": "977c88a02d7d3f16904a81907531b19666a08e78",
"shasum": ""
},
"require": {
@ -1139,7 +1139,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/config/tree/v5.4.40"
"source": "https://github.com/symfony/config/tree/v5.4.46"
},
"funding": [
{
@ -1155,20 +1155,20 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-10-30T07:58:02+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v2.5.3",
"version": "v2.5.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "80d075412b557d41002320b96a096ca65aa2c98d"
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d",
"reference": "80d075412b557d41002320b96a096ca65aa2c98d",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918",
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918",
"shasum": ""
},
"require": {
@ -1206,7 +1206,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3"
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4"
},
"funding": [
{
@ -1222,20 +1222,20 @@
"type": "tidelift"
}
],
"time": "2023-01-24T14:02:46+00:00"
"time": "2024-09-25T14:11:13+00:00"
},
{
"name": "symfony/filesystem",
"version": "v5.4.40",
"version": "v5.4.45",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "26dd9912df6940810ea00f8f53ad48d6a3424995"
"reference": "57c8294ed37d4a055b77057827c67f9558c95c54"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/26dd9912df6940810ea00f8f53ad48d6a3424995",
"reference": "26dd9912df6940810ea00f8f53ad48d6a3424995",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/57c8294ed37d4a055b77057827c67f9558c95c54",
"reference": "57c8294ed37d4a055b77057827c67f9558c95c54",
"shasum": ""
},
"require": {
@ -1273,7 +1273,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v5.4.40"
"source": "https://github.com/symfony/filesystem/tree/v5.4.45"
},
"funding": [
{
@ -1289,24 +1289,24 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-10-22T13:05:35+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.29.0",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": ""
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
@ -1352,7 +1352,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
},
"funding": [
{
@ -1368,24 +1368,24 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.29.0",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": ""
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
@ -1432,7 +1432,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
},
"funding": [
{
@ -1448,24 +1448,24 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.29.0",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"shasum": ""
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"type": "library",
"extra": {
@ -1512,7 +1512,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
},
"funding": [
{
@ -1528,24 +1528,24 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.29.0",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"shasum": ""
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"type": "library",
"extra": {
@ -1588,7 +1588,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
},
"funding": [
{
@ -1604,7 +1604,7 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "zf1s/zend-acl",
@ -3440,16 +3440,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.12.0",
"version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
"shasum": ""
},
"require": {
@ -3488,7 +3488,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.0"
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
},
"funding": [
{
@ -3496,7 +3496,7 @@
"type": "tidelift"
}
],
"time": "2024-06-12T14:39:25+00:00"
"time": "2024-11-08T17:47:46+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@ -3553,16 +3553,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.4.1",
"version": "5.6.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c"
"reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
"reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c",
"reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c",
"shasum": ""
},
"require": {
@ -3571,17 +3571,17 @@
"php": "^7.4 || ^8.0",
"phpdocumentor/reflection-common": "^2.2",
"phpdocumentor/type-resolver": "^1.7",
"phpstan/phpdoc-parser": "^1.7",
"phpstan/phpdoc-parser": "^1.7|^2.0",
"webmozart/assert": "^1.9.1"
},
"require-dev": {
"mockery/mockery": "~1.3.5",
"mockery/mockery": "~1.3.5 || ~1.6.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-webmozart-assert": "^1.2",
"phpunit/phpunit": "^9.5",
"vimeo/psalm": "^5.13"
"psalm/phar": "^5.26"
},
"type": "library",
"extra": {
@ -3611,29 +3611,29 @@
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1"
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0"
},
"time": "2024-05-21T05:55:05+00:00"
"time": "2024-11-12T11:25:25+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.8.2",
"version": "1.10.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "153ae662783729388a584b4361f2545e4d841e3c"
"reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
"reference": "153ae662783729388a584b4361f2545e4d841e3c",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
"reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1.0",
"php": "^7.3 || ^8.0",
"phpdocumentor/reflection-common": "^2.0",
"phpstan/phpdoc-parser": "^1.13"
"phpstan/phpdoc-parser": "^1.18|^2.0"
},
"require-dev": {
"ext-tokenizer": "*",
@ -3669,9 +3669,9 @@
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
},
"time": "2024-02-23T11:10:43+00:00"
"time": "2024-11-09T15:12:26+00:00"
},
{
"name": "phpspec/prophecy",
@ -3742,30 +3742,30 @@
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.29.1",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4"
"reference": "c00d78fb6b29658347f9d37ebe104bffadf36299"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4",
"reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299",
"reference": "c00d78fb6b29658347f9d37ebe104bffadf36299",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
"php": "^7.4 || ^8.0"
},
"require-dev": {
"doctrine/annotations": "^2.0",
"nikic/php-parser": "^4.15",
"nikic/php-parser": "^5.3.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^1.5",
"phpstan/phpstan-phpunit": "^1.1",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6",
"symfony/process": "^5.2"
},
"type": "library",
@ -3783,9 +3783,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1"
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0"
},
"time": "2024-05-31T08:52:43+00:00"
"time": "2024-10-13T11:29:49+00:00"
},
{
"name": "phpunit/dbunit",
@ -5079,6 +5079,6 @@
"platform": {
"php": "^7.4"
},
"platform-dev": [],
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ en_GB.UTF-8 UTF-8
en_US.UTF-8 UTF-8
es_ES.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8
nb_NO.UTF-8 UTF-8
hr_HR.UTF-8 UTF-8
hu_HU.UTF-8 UTF-8
it_IT.UTF-8 UTF-8

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ $(document).ready(function () {
[], //array of songs will be filled with below's json call
{
swfPath: baseUrl + "js/jplayer",
supplied: "oga, mp3, m4v, m4a, wav",
supplied: "oga, mp3, m4v, m4a, wav, flac",
size: {
width: "0px",
height: "0px",
@ -161,6 +161,12 @@ function buildplaylist(p_url, p_playIndex) {
artist: data[index]["element_artist"],
wav: data[index]["uri"],
};
} else if (data[index]["element_flac"] != undefined) {
media = {
title: data[index]["element_title"],
artist: data[index]["element_artist"],
flac: data[index]["uri"],
};
} else {
// skip this track since it's not supported
console.log("continue");
@ -177,6 +183,8 @@ function buildplaylist(p_url, p_playIndex) {
key = "m4a";
} else if (mime.search(/wav/i) > 0) {
key = "wav";
} else if (mime.search(/flac/i) > 0) {
key = "flac";
}
if (key) {
@ -243,6 +251,8 @@ function playOne(uri, mime) {
key = "m4a";
} else if (mime.search(/wav/i) > 0) {
key = "wav";
} else if (mime.search(/flac/i) > 0) {
key = "flac";
}
if (key) {

View File

@ -55,6 +55,7 @@ var AIRTIME = (function (AIRTIME) {
replay_gain: "n",
artwork: "s",
track_type_id: "tt",
filepath: "s",
};
if (AIRTIME.library === undefined) {
@ -843,6 +844,13 @@ var AIRTIME = (function (AIRTIME) {
sClass: "library_year",
sWidth: "60px",
},
/* File Name */ {
sTitle: $.i18n._("File Name"),
mDataProp: "filepath",
bVisible: false,
sClass: "library_file",
sWidth: "170px",
},
];
if (onDashboard) {
@ -858,7 +866,7 @@ var AIRTIME = (function (AIRTIME) {
);
}
var colExclude = onDashboard ? [0, 1, 2, 3, 34] : [0, 1, 2];
var colExclude = onDashboard ? [0, 1, 2, 3, 35] : [0, 1, 2];
/* ############################################
DATATABLES

View File

@ -0,0 +1,23 @@
{
"sEmptyTable": "No data available in table",
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
"sInfoFiltered": "(filtered from _MAX_ total entries)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Show _MENU_",
"sLoadingRecords": "Loading...",
"sProcessing": "Processing...",
"sSearch": "",
"sZeroRecords": "No matching records found",
"oPaginate": {
"sFirst": "First",
"sLast": "Last",
"sNext": "Next",
"sPrevious": "Previous"
},
"oAria": {
"sSortAscending": ": activate to sort column ascending",
"sSortDescending": ": activate to sort column descending"
}
}

View File

@ -17,21 +17,29 @@ Compress with: http://jscompress.com/
csvEncoding = 'data:text/csv;charset=utf-8,',
csvOutput = "",
csvRows = [],
BREAK = '\r\n',
BREAK = '\r\n', // Use CRLF for line breaks
DELIMITER = ',',
FILENAME = "export.csv";
FILENAME = "export.csv";
// Get and Write the headers
csvHeaders = Object.keys(csvData[0]);
csvOutput += csvHeaders.join(',') + BREAK;
csvOutput += csvHeaders.join(DELIMITER) + BREAK;
for (var i = 0; i < csvData.length; i++) {
var rowElements = [];
for(var k = 0; k < csvHeaders.length; k++) {
rowElements.push(csvData[i][csvHeaders[k]]);
} // Write the row array based on the headers
csvRows.push(rowElements.join(DELIMITER));
}
var rowElements = [];
for (var k = 0; k < csvHeaders.length; k++) {
var cell = csvData[i][csvHeaders[k]];
if (typeof cell === 'string') {
if (cell.includes('"')) {
cell = '"' + cell.replace(/"/g, '""') + '"'; // Escape double quotes by doubling them
} else if (cell.includes(DELIMITER) || cell.includes('\r') || cell.includes('\n')) {
cell = '"' + cell + '"'; // Enclose in double quotes if it contains commas, CR, or LF
}
}
rowElements.push(cell);
} // Write the row array based on the headers
csvRows.push(rowElements.join(DELIMITER));
}
csvOutput += csvRows.join(BREAK);

View File

@ -0,0 +1,27 @@
// Norwegian Bokmål (Norway)
plupload.addI18n({
'Select files' : 'Select files',
'Add files to the upload queue and click the start button.' : 'Add files to the upload queue and click the start button.',
'Filename' : 'Filename',
'Status' : 'Status',
'Size' : 'Size',
'Add files' : 'Add files',
'Stop current upload' : 'Stop current upload',
'Start uploading queue' : 'Start uploading queue',
'Uploaded %d/%d files': 'Uploaded %d/%d files',
'N/A' : 'N/A',
'Drag files here.' : 'Drag files here.',
'File extension error.': 'File extension error.',
'File size error.': 'File size error.',
'Init error.': 'Init error.',
'HTTP Error.': 'HTTP Error.',
'Security error.': 'Security error.',
'Generic error.': 'Generic error.',
'IO error.': 'IO error.',
'Stop Upload': 'Stop Upload',
'Add Files': 'Add Files',
'Start Upload': 'Start Upload',
'Start upload': 'Start upload',
'%d files queued': '%d files queued',
"Error: Invalid file extension: " : $.i18n._("Error: Invalid file extension: ")
});

View File

@ -16,6 +16,10 @@ cc_show:
has_autoplaylist: false
autoplaylist_id: null
autoplaylist_repeat: false
override_intro_playlist: false
intro_playlist_id: null
override_outro_playlist: false
outro_playlist_id: null
cc_show_days:
- id: "1"
first_show: "2014-01-05"

View File

@ -77,6 +77,10 @@ class ShowServiceDbTest extends Zend_Test_PHPUnit_DatabaseTestCase
'add_show_has_autoplaylist' => 0,
'add_show_autoplaylist_id' => null,
'add_show_autoplaylist_repeat' => 0,
'add_show_override_intro_playlist' => 0,
'add_show_intro_playlist_id' => null,
'add_show_override_outro_playlist' => 0,
'add_show_outro_playlist_id' => null,
];
$showService->setCcShow($data);

View File

@ -16,3 +16,7 @@ cc_show:
has_autoplaylist: false
autoplaylist_id: null
autoplaylist_repeat: false
override_intro_playlist: false
intro_playlist_id: null
override_outro_playlist: false
outro_playlist_id: null

Some files were not shown because too many files have changed in this diff Show More