episoder 0.10.1__tar.gz → 0.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- episoder-0.11.1/.gitignore +2 -0
- episoder-0.11.1/.gitlab-ci.yml +124 -0
- episoder-0.11.1/CHANGELOG +222 -0
- {episoder-0.10.1 → episoder-0.11.1}/PKG-INFO +6 -2
- {episoder-0.10.1 → episoder-0.11.1}/episoder/database.py +19 -18
- {episoder-0.10.1 → episoder-0.11.1}/episoder/episoder.py +38 -36
- {episoder-0.10.1 → episoder-0.11.1}/episoder/main.py +68 -84
- episoder-0.11.1/episoder/output.py +169 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder/sources/__init__.py +1 -1
- {episoder-0.10.1 → episoder-0.11.1}/episoder/sources/epguides.py +1 -1
- {episoder-0.10.1 → episoder-0.11.1}/episoder/sources/parser.py +1 -1
- {episoder-0.10.1 → episoder-0.11.1}/episoder/sources/thetvdb.py +3 -3
- {episoder-0.10.1 → episoder-0.11.1}/episoder/sources/tvcom.py +1 -1
- {episoder-0.10.1 → episoder-0.11.1}/episoder/version.py +2 -2
- episoder-0.11.1/episoder.1 +247 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder.egg-info/PKG-INFO +6 -2
- episoder-0.11.1/episoder.egg-info/SOURCES.txt +76 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder.egg-info/requires.txt +1 -1
- episoder-0.11.1/examples/home.episoder +30 -0
- {episoder-0.10.1 → episoder-0.11.1}/setup.cfg +1 -1
- episoder-0.11.1/test/__init__.py +0 -0
- episoder-0.11.1/test/fixtures/epguides_48_hours_mistery.html +399 -0
- episoder-0.11.1/test/fixtures/epguides_american_idol.html +872 -0
- episoder-0.11.1/test/fixtures/epguides_bsg.html +538 -0
- episoder-0.11.1/test/fixtures/epguides_buzzcocks.html +464 -0
- episoder-0.11.1/test/fixtures/epguides_doctor_who.html +842 -0
- episoder-0.11.1/test/fixtures/epguides_eureka.html +362 -0
- episoder-0.11.1/test/fixtures/epguides_futurama.html +407 -0
- episoder-0.11.1/test/fixtures/epguides_house.html +490 -0
- episoder-0.11.1/test/fixtures/epguides_kr2008.html +256 -0
- episoder-0.11.1/test/fixtures/epguides_lost.html +478 -0
- episoder-0.11.1/test/fixtures/epguides_lost_html.html +602 -0
- episoder-0.11.1/test/fixtures/epguides_lower_decks.html +340 -0
- episoder-0.11.1/test/fixtures/epguides_midsomer_murders.html +398 -0
- episoder-0.11.1/test/fixtures/epguides_picard.html +380 -0
- episoder-0.11.1/test/fixtures/epguides_test_iso_8859_1.html +138 -0
- episoder-0.11.1/test/fixtures/tvdb_error_404.json +3 -0
- episoder-0.11.1/test/fixtures/tvdb_search_frasier.json +10 -0
- episoder-0.11.1/test/fixtures/tvdb_search_friends.json +28 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_260.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_260_1_eps.json +19 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_261.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_261_1_eps.json +23 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_261_2_eps.json +23 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_261_3_eps.json +18 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_262.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_262_1_eps.json +20 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_263.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_268156.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_268156_1_eps.json +520 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_295640.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_295640_1_eps.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_295640_2_eps.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_73739.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_73739_1_eps.json +14 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_75397.json +1 -0
- episoder-0.11.1/test/fixtures/tvdb_test_show_75397_1_eps.json +1 -0
- {episoder-0.10.1 → episoder-0.11.1}/test/test_database.py +68 -68
- {episoder-0.10.1 → episoder-0.11.1}/test/test_epguides_parser.py +27 -23
- {episoder-0.10.1 → episoder-0.11.1}/test/test_episode.py +15 -15
- {episoder-0.10.1 → episoder-0.11.1}/test/test_metainfo.py +1 -1
- {episoder-0.10.1 → episoder-0.11.1}/test/test_migration.py +113 -125
- {episoder-0.10.1 → episoder-0.11.1}/test/test_notify.py +50 -77
- episoder-0.11.1/test/test_output.py +223 -0
- {episoder-0.10.1 → episoder-0.11.1}/test/test_show.py +14 -14
- {episoder-0.10.1 → episoder-0.11.1}/test/test_sources.py +4 -1
- {episoder-0.10.1 → episoder-0.11.1}/test/test_tvcom.py +2 -2
- {episoder-0.10.1 → episoder-0.11.1}/test/test_tvdb.py +29 -28
- episoder-0.11.1/test/util.py +60 -0
- episoder-0.10.1/episoder/output.py +0 -187
- episoder-0.10.1/episoder.egg-info/SOURCES.txt +0 -33
- episoder-0.10.1/test/test_output.py +0 -250
- {episoder-0.10.1 → episoder-0.11.1}/COPYING +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/README.md +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder/__init__.py +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder.egg-info/dependency_links.txt +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder.egg-info/entry_points.txt +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/episoder.egg-info/top_level.txt +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/pyproject.toml +0 -0
- {episoder-0.10.1 → episoder-0.11.1}/setup.py +0 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
stages:
|
|
2
|
+
- test
|
|
3
|
+
- deploy
|
|
4
|
+
|
|
5
|
+
.jammy_image: &jammy
|
|
6
|
+
image: registry.gitlab.com/schabe/episoder:ubuntu-jammy
|
|
7
|
+
|
|
8
|
+
.bookworm_image: &bookworm
|
|
9
|
+
image: registry.gitlab.com/schabe/episoder:debian-bookworm
|
|
10
|
+
|
|
11
|
+
.trixie_image: &trixie
|
|
12
|
+
image: registry.gitlab.com/schabe/episoder:debian-trixie
|
|
13
|
+
|
|
14
|
+
.noble_image: &noble
|
|
15
|
+
image: registry.gitlab.com/schabe/episoder:ubuntu-noble
|
|
16
|
+
|
|
17
|
+
.test_template: &test_installed_setuptools
|
|
18
|
+
stage: test
|
|
19
|
+
script:
|
|
20
|
+
- python3 setup.py install
|
|
21
|
+
- python3 -m pytest --junitxml=report.xml --cov=episoder/
|
|
22
|
+
- python3 -m coverage xml
|
|
23
|
+
artifacts:
|
|
24
|
+
reports:
|
|
25
|
+
junit: report.xml
|
|
26
|
+
coverage_report:
|
|
27
|
+
coverage_format: cobertura
|
|
28
|
+
path: coverage.xml
|
|
29
|
+
|
|
30
|
+
.test_template: &test
|
|
31
|
+
stage: test
|
|
32
|
+
script:
|
|
33
|
+
- python3 -m pytest --junitxml=report.xml --cov=episoder/
|
|
34
|
+
- python3 -m coverage xml
|
|
35
|
+
artifacts:
|
|
36
|
+
reports:
|
|
37
|
+
junit: report.xml
|
|
38
|
+
coverage_report:
|
|
39
|
+
coverage_format: cobertura
|
|
40
|
+
path: coverage.xml
|
|
41
|
+
|
|
42
|
+
.deploy_setuptools_template: &deploy_setuptools
|
|
43
|
+
stage: deploy
|
|
44
|
+
script:
|
|
45
|
+
- python3 setup.py install
|
|
46
|
+
- python3 setup.py sdist
|
|
47
|
+
- python3 setup.py bdist_egg
|
|
48
|
+
- episoder --version
|
|
49
|
+
|
|
50
|
+
.deploy_pip_template: &deploy_pip
|
|
51
|
+
stage: deploy
|
|
52
|
+
script:
|
|
53
|
+
- pip install .
|
|
54
|
+
- episoder --version
|
|
55
|
+
|
|
56
|
+
.deploy_setuptools_venv_template: &deploy_pip_venv
|
|
57
|
+
stage: deploy
|
|
58
|
+
script:
|
|
59
|
+
- python3 -m venv --system-site-packages venv
|
|
60
|
+
- venv/bin/python3 setup.py install
|
|
61
|
+
- venv/bin/python3 setup.py sdist
|
|
62
|
+
- venv/bin/python3 setup.py bdist_egg
|
|
63
|
+
- venv/bin/episoder --version
|
|
64
|
+
|
|
65
|
+
.deploy_pip_venv_template: &deploy_pip_venv
|
|
66
|
+
stage: deploy
|
|
67
|
+
script:
|
|
68
|
+
- python3 -m venv --system-site-packages venv
|
|
69
|
+
- venv/bin/pip install .
|
|
70
|
+
- venv/bin/episoder --version
|
|
71
|
+
|
|
72
|
+
py310-jammy:test:
|
|
73
|
+
<<: *jammy
|
|
74
|
+
<<: *test
|
|
75
|
+
|
|
76
|
+
py310-jammy-setuptools:deploy:
|
|
77
|
+
<<: *jammy
|
|
78
|
+
<<: *deploy_setuptools
|
|
79
|
+
|
|
80
|
+
py310-jammy-pip:deploy:
|
|
81
|
+
<<: *jammy
|
|
82
|
+
<<: *deploy_pip
|
|
83
|
+
|
|
84
|
+
py311-bookworm:test:
|
|
85
|
+
<<: *bookworm
|
|
86
|
+
<<: *test
|
|
87
|
+
|
|
88
|
+
py311-bookworm-setuptools:deploy:
|
|
89
|
+
needs: ["py311-bookworm:test"]
|
|
90
|
+
<<: *bookworm
|
|
91
|
+
<<: *deploy_setuptools
|
|
92
|
+
|
|
93
|
+
py311-bookworm-pip:deploy:
|
|
94
|
+
needs: ["py311-bookworm:test"]
|
|
95
|
+
<<: *bookworm
|
|
96
|
+
<<: *deploy_pip_venv
|
|
97
|
+
|
|
98
|
+
py312-noble:test:
|
|
99
|
+
<<: *noble
|
|
100
|
+
<<: *test
|
|
101
|
+
|
|
102
|
+
py312-noble-setuptools:deploy:
|
|
103
|
+
needs: ["py312-noble:test"]
|
|
104
|
+
<<: *noble
|
|
105
|
+
<<: *deploy_setuptools
|
|
106
|
+
|
|
107
|
+
py312-noble-pip:deploy:
|
|
108
|
+
needs: ["py312-noble:test"]
|
|
109
|
+
<<: *noble
|
|
110
|
+
<<: *deploy_pip_venv
|
|
111
|
+
|
|
112
|
+
py313-trixie:test:
|
|
113
|
+
<<: *trixie
|
|
114
|
+
<<: *test
|
|
115
|
+
|
|
116
|
+
py313-trixie-setuptools:deploy:
|
|
117
|
+
needs: ["py313-trixie:test"]
|
|
118
|
+
<<: *trixie
|
|
119
|
+
<<: *deploy_setuptools
|
|
120
|
+
|
|
121
|
+
py313-trixie-pip:deploy:
|
|
122
|
+
needs: ["py313-trixie:test"]
|
|
123
|
+
<<: *trixie
|
|
124
|
+
<<: *deploy_pip_venv
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
== 0.11.1 (8 Apr 2025) ==
|
|
2
|
+
* Use Python's EmailMessage class when sending e-mail
|
|
3
|
+
|
|
4
|
+
== 0.11.0 (20 Jul 2024) ==
|
|
5
|
+
* Port to sqlalchemy 2.0
|
|
6
|
+
|
|
7
|
+
== 0.10.1 (17 May 2023) ==
|
|
8
|
+
* tvdb: Fix a crash on shows with an empty 'data' field
|
|
9
|
+
* epguides: Fix parsing of cancelled/ended shows
|
|
10
|
+
|
|
11
|
+
== 0.10.0 (25 Mar 2023) ==
|
|
12
|
+
* Fix a crash when trying to render shows without a name
|
|
13
|
+
* Explicitly depend on sqlalchemy 1.3/1.4
|
|
14
|
+
* Fix code that sets the database schema version
|
|
15
|
+
* Rename package from pyepisoder to episoder
|
|
16
|
+
* Update distribution scripts
|
|
17
|
+
|
|
18
|
+
== 0.9.2 (1 Jan 2021) ==
|
|
19
|
+
* Fix a crash when trying to render episodes without production number
|
|
20
|
+
* Use appropriate colors when showing episodes from a past date
|
|
21
|
+
* Fix formatting of show names in list of shows
|
|
22
|
+
* Accept empty episode lines in epguide HTML format parser
|
|
23
|
+
|
|
24
|
+
== 0.9.1 (11 Oct 2020) ==
|
|
25
|
+
* Fix setup.py
|
|
26
|
+
|
|
27
|
+
== 0.9.0 (11 Oct 2020) ==
|
|
28
|
+
* Add support for new HTML format on epguides.com (thanks to Jethro Beekman)
|
|
29
|
+
|
|
30
|
+
== 0.8.5 (28 Mar 2020) ==
|
|
31
|
+
* Fix a small bug in setup.py
|
|
32
|
+
|
|
33
|
+
== 0.8.4 (28 Mar 2020) ==
|
|
34
|
+
* Fix loading of shows without episodes from TVDB
|
|
35
|
+
* Fix loading of episodes with invalid date (0000-00-00)
|
|
36
|
+
|
|
37
|
+
== 0.8.3 (27 Sep 2017) ==
|
|
38
|
+
* Fixed a crash related to unexpected null values in TVDB JSON data
|
|
39
|
+
* Use correct path for example config file in setup.py (fixes #7)
|
|
40
|
+
|
|
41
|
+
== 0.8.2 (7 Jul 2017) ==
|
|
42
|
+
* Fixed a crash when rendering episodes without a title
|
|
43
|
+
|
|
44
|
+
== 0.8.1 (24 Jun 2017) ==
|
|
45
|
+
* Handle failures to load TVDB API pages
|
|
46
|
+
|
|
47
|
+
== 0.8.0 (7 Jun 2017) ==
|
|
48
|
+
* Switched from distutils to setuptools
|
|
49
|
+
* We now use the new TVDB JSON API
|
|
50
|
+
* Rewrote the epguides.com parser in pure Python
|
|
51
|
+
* Rewrote large parts of the database code
|
|
52
|
+
* Episoder should now work fully with Python 3
|
|
53
|
+
* The update command can now be limited to a fixed number of shows
|
|
54
|
+
* Updated man page
|
|
55
|
+
* Thanks to Chris Spencer (chrisspen) for his contributions
|
|
56
|
+
* Added option to only list active shows (chrisspen)
|
|
57
|
+
* Added the number of episodes to the list of shows (chrisspen)
|
|
58
|
+
* Added email notification feature via 'episoder notify' (chrisspen)
|
|
59
|
+
|
|
60
|
+
== 0.7.3 (7 Nov 2015) ==
|
|
61
|
+
* Fixed a syntax error in the list of shows
|
|
62
|
+
* Fixed season number parsing for epguides.com (thanks to jethrogb)
|
|
63
|
+
|
|
64
|
+
== 0.7.2 (26 Sep 2015) ==
|
|
65
|
+
* Dropped unneeded dependency on BeautifulSoup
|
|
66
|
+
* Fixed episode number parsing for epguides.com (thanks to jethrogb)
|
|
67
|
+
* Improved python3 compatibility
|
|
68
|
+
|
|
69
|
+
== 0.7.1 (27 Apr 2014) ==
|
|
70
|
+
* Accept unicode characters in prodnum fields
|
|
71
|
+
|
|
72
|
+
== 0.7.0 (14 Oct 2013) ==
|
|
73
|
+
* Added support for TheTVDB.com
|
|
74
|
+
* Removed support for tv.com
|
|
75
|
+
* Changed command-line arguments. See the man page for details
|
|
76
|
+
* Removed the ability to specify shows in the configuration file
|
|
77
|
+
* Reorganized the command line options. Check the documentation for details
|
|
78
|
+
* Updated the epguides.com parser to ignore trailer links in episode names
|
|
79
|
+
* Fixed some more encoding issues in the console renderer
|
|
80
|
+
* Changed license to GPLv3
|
|
81
|
+
|
|
82
|
+
== 0.6.5 (6 Oct 2010) ==
|
|
83
|
+
* Updated the epguides.com parser to ignore links to trailers in episode names
|
|
84
|
+
|
|
85
|
+
== 0.6.4 (25 Jun 2010) ==
|
|
86
|
+
* Filter javascript from tv.com pages because it confuses beautifulsoup 3.1
|
|
87
|
+
|
|
88
|
+
== 0.6.3 (23 Jun 2010) ==
|
|
89
|
+
* The epguides parser now properly reads the season number for more shows
|
|
90
|
+
|
|
91
|
+
== 0.6.2 (08 Nov 2009) ==
|
|
92
|
+
* Updated tv.com parser (show names need to be lower-case now!)
|
|
93
|
+
* Added -S option to specify a show id for (forced) updates
|
|
94
|
+
|
|
95
|
+
== 0.6.1 (26 Aug 2009) ==
|
|
96
|
+
* Episoder can now talk to any database supported by sqlalchemy (see README)
|
|
97
|
+
* Tell awk to process utf8 (for epguides parser)
|
|
98
|
+
* Catch (and properly log) some more HTTP exceptions
|
|
99
|
+
|
|
100
|
+
== 0.6.0 (8 Aug 2009) ==
|
|
101
|
+
* Episoder now keeps a persistent database of shows and episodes
|
|
102
|
+
* Added new options (-L, -a, -r, -E, -D) to manage the database
|
|
103
|
+
* The parsers now know whether a show is still running or not
|
|
104
|
+
* Active (currently running) shows are updated every two days
|
|
105
|
+
* Inactive (ended) shows are updated every two weeks
|
|
106
|
+
* The new -B command overrides those intervals and forces an update
|
|
107
|
+
* Show names can no longer be overridden in the configuration file
|
|
108
|
+
* Don't report an error when no sources are defined in the config file
|
|
109
|
+
* The tv.com parser now also accepts urls containing '!', '+' or '%'
|
|
110
|
+
* The -d option now also accepts the number of days instead of a fixed date
|
|
111
|
+
* Documentation updated
|
|
112
|
+
|
|
113
|
+
== 0.5.3 (26 Jul 2009) ==
|
|
114
|
+
* Added support for another epguides formatting style (used eg. for "Eureka")
|
|
115
|
+
* Added option to suppress colors in console output
|
|
116
|
+
* Added a filter to remove invalid characters from epguides content
|
|
117
|
+
* Fixed some other parsing issues in the epguides parser
|
|
118
|
+
* Improved compatibility with older python versions
|
|
119
|
+
|
|
120
|
+
== 0.5.2 (30 Jun 2009) ==
|
|
121
|
+
* Reworked parts of the code to improve compatibility with older libraries
|
|
122
|
+
* Fixed some encoding issues in the console renderer
|
|
123
|
+
|
|
124
|
+
== 0.5.1 (23 Jun 2009) ==
|
|
125
|
+
* Thanks to Philip Douglass for his bug reports and patches
|
|
126
|
+
* The epguides parser now properly closes all file handles and works with mawk
|
|
127
|
+
* The tv.com parser would crash on missing production/season/episode numbers
|
|
128
|
+
* The tv.com parser now accepts urls that contain a dash
|
|
129
|
+
* Switched to using sqlalchemy to access the database
|
|
130
|
+
* Properly implemented the user-agent configuration option
|
|
131
|
+
* Removed old FAQ
|
|
132
|
+
* Fixed some text encoding issues
|
|
133
|
+
* Small fixes to the man page
|
|
134
|
+
|
|
135
|
+
== 0.5.0 (18 May 2009) ==
|
|
136
|
+
* Rewrote the whole thing in python
|
|
137
|
+
* Wrote a brand new tv.com parser
|
|
138
|
+
* Small fixes in the epguides.com parser
|
|
139
|
+
* Parsed data is now stored in an sqlite3 database
|
|
140
|
+
|
|
141
|
+
== 0.4.7 (24 Feb 2007) ==
|
|
142
|
+
* Fixed a parsing issue introduced with 0.4.6
|
|
143
|
+
|
|
144
|
+
== 0.4.6 (24 Feb 2007) ==
|
|
145
|
+
* Discovered yet another formatting possibility on epguides.com (used for
|
|
146
|
+
instance for the show "Midsomer Murders") and adapted the parser accordingly
|
|
147
|
+
* Slightly updated the man page
|
|
148
|
+
|
|
149
|
+
== 0.4.5 (23 Jan 2007) ==
|
|
150
|
+
* Fixed some epguides parser issues
|
|
151
|
+
|
|
152
|
+
== 0.4.4 (19 Nov 2006) ==
|
|
153
|
+
* Fixed the -i option when building the database (did the exact opposite of
|
|
154
|
+
what it was supposed to do)
|
|
155
|
+
|
|
156
|
+
== 0.4.3 (24 Oct 2006) ==
|
|
157
|
+
* We now actually honor the -i option when building the database
|
|
158
|
+
* Added the possibility to override a show's name in the config file. This was needed for the new webisoder, a web-based episoder. Find out more about it at http://www.webisoder.net/
|
|
159
|
+
* Oops, forgot to update episoder's version number in the last release...
|
|
160
|
+
* Fixed a bug in the new epguides.com parser which would not drop episodes without a date
|
|
161
|
+
|
|
162
|
+
== 0.4.2 (21 Oct 2006) ==
|
|
163
|
+
* Don't ignore the config file passed with -c anymore when building the db
|
|
164
|
+
* Added parser for epguides.com (closes #38)
|
|
165
|
+
|
|
166
|
+
== 0.4.1 (20 Apr 2006) ==
|
|
167
|
+
* Did some minor internal changes to get episoder to work on non-linux systems
|
|
168
|
+
* Removed long options
|
|
169
|
+
* Hotfix for the tv.com website changes
|
|
170
|
+
|
|
171
|
+
== 0.4.0 (3 Dec 2005) ==
|
|
172
|
+
* Re-organized options: -vv is now -w, -rc is now -c (or --rc), -nd is gone (use --nodate), -sa is gone (use -s and --nodate instead), -i is gone (see below)
|
|
173
|
+
* Search is now alway case-insensitive
|
|
174
|
+
* If no action is specified, episoder now defaults to showlist
|
|
175
|
+
* Removed the tvtome dummy plugin
|
|
176
|
+
|
|
177
|
+
== 0.3.0 (9 Aug 2005) ==
|
|
178
|
+
* Majeed Goldrick joined the project
|
|
179
|
+
* Moved parts of the website to sourceforge
|
|
180
|
+
* Removed a 1024-episodes-limit in sortlist
|
|
181
|
+
* Added search options
|
|
182
|
+
* Switched to awk to remove old episodes (>600 times faster)
|
|
183
|
+
* Switched to awk for tv.com parsing (>10 times faster)
|
|
184
|
+
* Removed the debian files from the main distribution
|
|
185
|
+
* Added a couple of tests
|
|
186
|
+
|
|
187
|
+
== 0.2.5 (19 Jul 2005) ==
|
|
188
|
+
* Fixed an alignment problem in showlist (closes #25)
|
|
189
|
+
* Fixed a date-calculation issue in showlist (closes #23)
|
|
190
|
+
* Fixed a documentation mistake about the format string (closes #21)
|
|
191
|
+
* Added support for nun-numeric episode numbers (closes #24)
|
|
192
|
+
|
|
193
|
+
== 0.2.4 (19 Jul 2005) ==
|
|
194
|
+
* Re-arranged the code to remove a 3-episodes-limit in showlist (closes #19)
|
|
195
|
+
* Added command line option to specify the number of days to show (closes #20)
|
|
196
|
+
* Brought back season-episode information in the tvcom plugin (closes #15)
|
|
197
|
+
* Added the possibility to customize the output format (closes #16)
|
|
198
|
+
* Added a small FAQ
|
|
199
|
+
* Thanks to Majeed Goldrick for all the bug reports and feature suggestions
|
|
200
|
+
* Cosmetic changes
|
|
201
|
+
|
|
202
|
+
== 0.2.3 (23 Jun 2005) ==
|
|
203
|
+
* The tvcom plugin now uses the new "All Seasons" link
|
|
204
|
+
* Cosmetic changes
|
|
205
|
+
|
|
206
|
+
== 0.2.2 (17 Jun 2005) ==
|
|
207
|
+
* Added LICENSE file
|
|
208
|
+
* install.sh now correctly changes the EPISODER_HOME value
|
|
209
|
+
* Small fixes in the verbose output
|
|
210
|
+
* Created tvcom plugin
|
|
211
|
+
* Replaced all functionality from the tvtome plugin with a warning
|
|
212
|
+
* Now all the available modules are actually loaded
|
|
213
|
+
* Some minor changes in the man page
|
|
214
|
+
|
|
215
|
+
== 0.2.1 (4 Jan 2005) ==
|
|
216
|
+
* The tvtome plugin now understands UNAIRED episodes
|
|
217
|
+
* Improved the builddb script's debug output
|
|
218
|
+
* Fixed an issue that would print errors for shows with no upcoming episodes
|
|
219
|
+
* The debian files are now part of the main distribution
|
|
220
|
+
|
|
221
|
+
== 0.2.0 (13 Sep 2004) ==
|
|
222
|
+
* Initial public release
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: episoder
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: TV episode notifier
|
|
5
5
|
Home-page: https://code.ott.net/episoder/
|
|
6
6
|
Author: Stefan Ott
|
|
@@ -17,6 +17,10 @@ Classifier: Topic :: Multimedia :: Video
|
|
|
17
17
|
Requires-Python: >=3.6
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: COPYING
|
|
20
|
+
Requires-Dist: argparse
|
|
21
|
+
Requires-Dist: requests
|
|
22
|
+
Requires-Dist: beautifulsoup4
|
|
23
|
+
Requires-Dist: sqlalchemy>=1.3
|
|
20
24
|
|
|
21
25
|
# episoder
|
|
22
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# episoder, https://code.ott.net/episoder
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2004-
|
|
3
|
+
# Copyright (C) 2004-2024 Stefan Ott. All rights reserved.
|
|
4
4
|
#
|
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -21,8 +21,7 @@ from datetime import datetime
|
|
|
21
21
|
|
|
22
22
|
from sqlalchemy import Column, Integer, Text, Date, ForeignKey, Sequence
|
|
23
23
|
from sqlalchemy import DateTime, Boolean
|
|
24
|
-
from sqlalchemy.
|
|
25
|
-
from sqlalchemy.orm import relationship, backref
|
|
24
|
+
from sqlalchemy.orm import backref, declarative_base, relationship
|
|
26
25
|
|
|
27
26
|
Base = declarative_base()
|
|
28
27
|
|
|
@@ -36,14 +35,14 @@ class Show(Base):
|
|
|
36
35
|
__tablename__ = "shows"
|
|
37
36
|
|
|
38
37
|
id = Column("show_id", Integer, Sequence("shows_show_id_seq"),
|
|
39
|
-
|
|
38
|
+
primary_key=True)
|
|
40
39
|
name = Column("show_name", Text)
|
|
41
40
|
url = Column(Text, unique=True)
|
|
42
41
|
updated = Column(DateTime)
|
|
43
42
|
enabled = Column(Boolean)
|
|
44
43
|
status = Column(Integer, default=RUNNING)
|
|
45
44
|
|
|
46
|
-
def __init__(self, name, url=
|
|
45
|
+
def __init__(self, name, url="", updated=datetime.fromtimestamp(0)):
|
|
47
46
|
|
|
48
47
|
self.name = name
|
|
49
48
|
self.url = url
|
|
@@ -54,11 +53,11 @@ class Show(Base):
|
|
|
54
53
|
|
|
55
54
|
def __str__(self):
|
|
56
55
|
|
|
57
|
-
return "Show:
|
|
56
|
+
return f"Show: {self.name}"
|
|
58
57
|
|
|
59
58
|
def __repr__(self):
|
|
60
59
|
|
|
61
|
-
return 'Show(
|
|
60
|
+
return f'Show("{self.name}", "{self.url}")'
|
|
62
61
|
|
|
63
62
|
def __eq__(self, other):
|
|
64
63
|
|
|
@@ -84,6 +83,7 @@ class Episode(Base):
|
|
|
84
83
|
notified = Column(Date)
|
|
85
84
|
show = relationship(Show, backref=backref("episodes", cascade="all"))
|
|
86
85
|
|
|
86
|
+
# pylint: disable=too-many-arguments,too-many-positional-arguments
|
|
87
87
|
def __init__(self, name, season, episode, aired, prodnum, total):
|
|
88
88
|
|
|
89
89
|
self.title = name
|
|
@@ -96,26 +96,27 @@ class Episode(Base):
|
|
|
96
96
|
def __lt__(self, other):
|
|
97
97
|
|
|
98
98
|
return ((self.season < other.season)
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
or ((self.season == other.season)
|
|
100
|
+
and (self.episode < other.episode)))
|
|
101
101
|
|
|
102
102
|
def __str__(self):
|
|
103
103
|
|
|
104
|
-
return "
|
|
105
|
-
|
|
104
|
+
return f"{self.show.name} {self.season}x{self.episode:02d}: " \
|
|
105
|
+
f"{self.title}"
|
|
106
106
|
|
|
107
107
|
def __repr__(self):
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
d = self.airdate
|
|
110
|
+
|
|
111
|
+
return f'Episode("{self.title}", {self.season}, {self.episode}, ' \
|
|
112
|
+
f'date({d.year}, {d.month}, {d.day}), "{self.prodnum}", ' \
|
|
113
|
+
f'{self.totalnum})'
|
|
113
114
|
|
|
114
115
|
def __eq__(self, other):
|
|
115
116
|
|
|
116
117
|
return (self.show_id == other.show_id
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
and self.season == other.season
|
|
119
|
+
and self.episode == other.episode)
|
|
119
120
|
|
|
120
121
|
|
|
121
122
|
class Meta(Base):
|
|
@@ -126,7 +127,7 @@ class Meta(Base):
|
|
|
126
127
|
|
|
127
128
|
def __str__(self):
|
|
128
129
|
|
|
129
|
-
return "Meta:
|
|
130
|
+
return f"Meta: {self.key} = {self.value}"
|
|
130
131
|
|
|
131
132
|
def __repr__(self):
|
|
132
133
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# episoder, https://code.ott.net/episoder
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2004-
|
|
3
|
+
# Copyright (C) 2004-2024 Stefan Ott. All rights reserved.
|
|
4
4
|
#
|
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -19,8 +19,8 @@ import logging
|
|
|
19
19
|
from datetime import date, timedelta
|
|
20
20
|
|
|
21
21
|
import sqlite3
|
|
22
|
-
from sqlalchemy import
|
|
23
|
-
from sqlalchemy.orm import
|
|
22
|
+
from sqlalchemy import create_engine, or_, and_, select, inspect
|
|
23
|
+
from sqlalchemy.orm import sessionmaker
|
|
24
24
|
|
|
25
25
|
from .database import Episode, Show, Meta
|
|
26
26
|
|
|
@@ -37,20 +37,21 @@ class Database:
|
|
|
37
37
|
|
|
38
38
|
def __str__(self):
|
|
39
39
|
|
|
40
|
-
return "Episoder Database at
|
|
40
|
+
return f"Episoder Database at {self._path}"
|
|
41
41
|
|
|
42
42
|
def __repr__(self):
|
|
43
43
|
|
|
44
|
-
return "Database(
|
|
44
|
+
return f"Database({self._path})"
|
|
45
45
|
|
|
46
46
|
def _initdb(self):
|
|
47
47
|
|
|
48
|
+
inspector = inspect(self.engine)
|
|
49
|
+
|
|
48
50
|
# Initialize the database if all tables are missing
|
|
49
|
-
|
|
50
|
-
tables =
|
|
51
|
-
found = [x for x in tables if x(bind=self.engine)]
|
|
51
|
+
names = [Show, Episode, Meta]
|
|
52
|
+
tables = [t for t in names if inspector.has_table(t.__table__.name)]
|
|
52
53
|
|
|
53
|
-
if len(
|
|
54
|
+
if len(tables) < 1:
|
|
54
55
|
Show.__table__.create(bind=self.engine)
|
|
55
56
|
Episode.__table__.create(bind=self.engine)
|
|
56
57
|
Meta.__table__.create(bind=self.engine)
|
|
@@ -61,36 +62,35 @@ class Database:
|
|
|
61
62
|
if self._path.find("://") > -1:
|
|
62
63
|
self.engine = create_engine(self._path)
|
|
63
64
|
else:
|
|
64
|
-
self.engine = create_engine("sqlite
|
|
65
|
+
self.engine = create_engine(f"sqlite:///{self._path}")
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
self.
|
|
68
|
-
self.metadata.bind = self.engine
|
|
69
|
-
self.session = create_session(bind=self.engine)
|
|
67
|
+
sm = sessionmaker(self.engine)
|
|
68
|
+
self.session = sm()
|
|
70
69
|
self.session.begin()
|
|
71
70
|
|
|
72
71
|
def close(self):
|
|
73
72
|
|
|
74
73
|
self.session.commit()
|
|
75
74
|
self.session.close()
|
|
76
|
-
self.conn.close()
|
|
77
75
|
self.engine.dispose()
|
|
78
76
|
|
|
79
77
|
def set_schema_version(self, version):
|
|
80
78
|
|
|
81
79
|
meta = Meta()
|
|
82
80
|
meta.key = "schema"
|
|
83
|
-
meta.value = "
|
|
81
|
+
meta.value = f"{version}"
|
|
84
82
|
|
|
85
83
|
with self.session.begin_nested():
|
|
86
84
|
self.session.merge(meta)
|
|
87
85
|
|
|
88
86
|
def get_schema_version(self):
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
inspector = inspect(self.engine)
|
|
89
|
+
if not inspector.has_table(Meta.__table__.name):
|
|
91
90
|
return 1
|
|
92
91
|
|
|
93
|
-
res = self.session.
|
|
92
|
+
res = self.session.scalars(
|
|
93
|
+
select(Meta).where(Meta.key == "schema")).first()
|
|
94
94
|
if res:
|
|
95
95
|
return int(res.value)
|
|
96
96
|
|
|
@@ -121,11 +121,10 @@ class Database:
|
|
|
121
121
|
# simply drop and re-create the tables
|
|
122
122
|
self.logger.debug("Upgrading to schema version 2")
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
table.drop()
|
|
124
|
+
upgrade = sqlite3.connect(self._path)
|
|
125
|
+
upgrade.execute("DROP TABLE episodes")
|
|
126
|
+
upgrade.execute("DROP TABLE shows")
|
|
127
|
+
upgrade.close()
|
|
129
128
|
|
|
130
129
|
Show.__table__.create(bind=self.engine)
|
|
131
130
|
Episode.__table__.create(bind=self.engine)
|
|
@@ -146,9 +145,9 @@ class Database:
|
|
|
146
145
|
|
|
147
146
|
upgrade = sqlite3.connect(self._path)
|
|
148
147
|
upgrade.execute("ALTER TABLE shows "
|
|
149
|
-
|
|
148
|
+
"ADD COLUMN enabled TYPE boolean")
|
|
150
149
|
upgrade.execute("ALTER TABLE shows "
|
|
151
|
-
|
|
150
|
+
"ADD COLUMN status TYPE integer")
|
|
152
151
|
upgrade.close()
|
|
153
152
|
|
|
154
153
|
self.open()
|
|
@@ -167,7 +166,7 @@ class Database:
|
|
|
167
166
|
|
|
168
167
|
upgrade = sqlite3.connect(self._path)
|
|
169
168
|
upgrade.execute("ALTER TABLE episodes "
|
|
170
|
-
|
|
169
|
+
"ADD COLUMN notified TYPE date")
|
|
171
170
|
upgrade.close()
|
|
172
171
|
|
|
173
172
|
self.open()
|
|
@@ -216,7 +215,8 @@ class Database:
|
|
|
216
215
|
|
|
217
216
|
def get_show_by_id(self, show_id):
|
|
218
217
|
|
|
219
|
-
return self.session.
|
|
218
|
+
return self.session.scalars(
|
|
219
|
+
select(Show).where(Show.id == show_id)).first()
|
|
220
220
|
|
|
221
221
|
def add_show(self, show):
|
|
222
222
|
|
|
@@ -226,15 +226,17 @@ class Database:
|
|
|
226
226
|
|
|
227
227
|
def remove_show(self, show_id):
|
|
228
228
|
|
|
229
|
-
show = self.session.
|
|
229
|
+
show = self.session.scalars(
|
|
230
|
+
select(Show).where(Show.id == show_id)).first()
|
|
230
231
|
|
|
231
232
|
if not show:
|
|
232
233
|
self.logger.error("No such show")
|
|
233
234
|
return
|
|
234
235
|
|
|
235
|
-
episodes = self.session.
|
|
236
|
+
episodes = self.session.scalars(select(Episode))
|
|
236
237
|
|
|
237
|
-
for
|
|
238
|
+
hits = [e for e in episodes if e.show_id == show.id]
|
|
239
|
+
for episode in hits:
|
|
238
240
|
self.session.delete(episode)
|
|
239
241
|
|
|
240
242
|
self.session.delete(show)
|
|
@@ -254,18 +256,18 @@ class Database:
|
|
|
254
256
|
|
|
255
257
|
enddate = basedate + timedelta(n_days)
|
|
256
258
|
|
|
257
|
-
return self.session.query(Episode)
|
|
259
|
+
return self.session.query(Episode). \
|
|
258
260
|
filter(Episode.airdate >= basedate). \
|
|
259
261
|
filter(Episode.airdate <= enddate). \
|
|
260
262
|
order_by(Episode.airdate).all()
|
|
261
263
|
|
|
262
264
|
def search(self, search):
|
|
263
265
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
Episode.title.like("
|
|
267
|
-
Show.name.like("
|
|
268
|
-
order_by(Episode.airdate).all()
|
|
266
|
+
q = self.session.query(Episode).join(Episode.show)
|
|
267
|
+
return q.filter(or_(
|
|
268
|
+
Episode.title.like(f"%%{search}%%"),
|
|
269
|
+
Show.name.like(f"%%{search}%%"))). \
|
|
270
|
+
order_by(Episode.airdate.asc()).all()
|
|
269
271
|
|
|
270
272
|
def commit(self):
|
|
271
273
|
|