Modul Python dirancang untuk mengunduh file dari RSS feed tertentu, khususnya ditargetkan pada podcast. Itu tidak menggunakan database apa pun tetapi memerlukan file konfigurasi.
Script ini dimaksudkan untuk dijalankan secara berkala. Saat memulai, ia menganalisis direktori tempat file yang diunduh sebelumnya disimpan. Ia kemudian membandingkan file-file ini dengan yang terdaftar di RSS feed, mengidentifikasi file yang hilang dan mendownloadnya.
File yang dicari secara default adalah mp3
.
Hasil dari penggunaan contoh di bawah ini, pada direktori kosong adalah:
dplocki@ghost-wheel:~$ python -m podcast_downloader
[2024-04-08 21:19:10] Loading configuration (from file: "~/.podcast_downloader_config.json")
[2024-04-08 21:19:15] Checking "The Skeptic Guide"
[2024-04-08 21:19:15] Last downloaded file ""
[2024-04-08 21:19:15] The Skeptic Guide: Downloading file: "https://traffic.libsyn.com/secure/skepticsguide/skepticast2024-04-06.mp3" saved as "skepticast2024-04-06.mp3"
[2024-04-08 21:19:41] Checking "The Real Python Podcast"
[2024-04-08 21:19:41] Last downloaded file ""
[2024-04-08 21:19:41] The Real Python Podcast: Downloading file: "https://chtbl.com/track/92DB94/files.realpython.com/podcasts/RPP_E199_03_Calvin.eef1db4d6679.mp3" saved as "[20240405] rpp_e199_03_calvin.eef1db4d6679.mp3"
[2024-04-08 21:20:04] Finished
Hasilnya:
dplocki@ghost-wheel:~$ tree podcasts/
podcasts/
├── RealPython
│ └── [20240405] rpp_e199_03_calvin.eef1db4d6679.mp3
└── SGTTU
└── skepticast2024-04-06.mp3
2 directories, 2 files
Instalasi dari PyPI:
pip install podcast_downloader
Skrip memerlukan file konfigurasi agar dapat berfungsi. Setelah instalasi, skrip dapat dijalankan seperti modul Python apa pun:
python -m podcast_downloader
Dimungkinkan juga untuk menjalankan skrip dengan file konfigurasi yang diberikan:
python -m podcast_downloader --config my_config.json
Contoh file konfigurasi
{
"if_directory_empty" : " download_from_4_days " ,
"podcasts" : [
{
"name" : " The Skeptic Guide " ,
"rss_link" : " https://feed.theskepticsguide.org/feed/rss.aspx " ,
"path" : " ~/podcasts/SGTTU "
},
{
"rss_link" : " https://realpython.com/podcasts/rpp/feed " ,
"path" : " ~/podcasts/RealPython " ,
"file_name_template" : " [%publish_date%] %file_name%.%file_extension% "
}
]
}
Secara default file konfigurasi ditempatkan di direktori home. Nama filenya adalah: .podcast_downloader_config.json
.
File konfigurasi diformat dalam JSON. Pengkodean yang diharapkan adalah utf-8.
Jalur ke file konfigurasi dapat ditentukan dengan argumen skrip.
Skrip menggantikan nilai default dengan nilai yang dibaca dari file konfigurasi. Itu akan dibebani dengan nilai yang diberikan dari baris perintah.
command line parameters > configuration file > default values
Milik | Jenis | Diperlukan? | Bawaan | Catatan |
---|---|---|---|---|
downloads_limit | nomor | TIDAK | ketakterbatasan | |
if_directory_empty | rangkaian | TIDAK | unduh_terakhir | Lihat Jika direktori kosong |
podcast_extensions | nilai kunci | TIDAK | {".mp3": "audio/mpeg"} | Lihat Filter jenis file |
podcasts | ayat | Ya | [] | Lihat sub kategori Podcast |
http_headers | nilai kunci | TIDAK | {"User-Agent": "podcast-downloader"} | Lihat header permintaan HTTP |
fill_up_gaps | boolean | TIDAK | PALSU | Lihat Mengunduh file dari celah |
download_delay | nomor | TIDAK | 0 | Lihat Penundaan pengunduhan |
Segmen podcasts
adalah bagian dari file konfigurasi tempat Anda menyediakan array objek dengan konten berikut:
Milik | Jenis | Diperlukan | Bawaan | Catatan |
---|---|---|---|---|
name | rangkaian | Ya | - | Nama saluran (digunakan dalam logger) |
rss_link | rangkaian | Ya | - | URL umpan RSS |
path | rangkaian | Ya | - | Jalur ke direktori tempat podcast disimpan akan diunduh |
file_name_template | rangkaian | TIDAK | %file_name%.%file_extension% | Templat untuk file yang diunduh, lihat Templat nama file |
disable | boolean | TIDAK | false | Podcast ini akan diabaikan |
podcast_extensions | nilai kunci | TIDAK | {".mp3": "audio/mpeg"} | Penyaring berkas |
if_directory_empty | rangkaian | TIDAK | download_last | Lihat Jika direktori kosong |
require_date | boolean | TIDAK | false | Tidak berlaku lagi Apakah tanggal podcast harus ditambahkan ke nama file - gunakan file_name_template : [%publish_date%] %file_name%.%file_extension%" |
http_headers | nilai kunci | TIDAK | {"User-Agent": "podcast-downloader"} | Lihat header permintaan HTTP |
fill_up_gaps | boolean | TIDAK | PALSU | Lihat Mengunduh file dari celah |
Beberapa server mungkin tidak menyukai cara urllib menampilkan dirinya kepada mereka (header Agen-Pengguna HTTP). Hal ini dapat menyebabkan masalah seperti: urllib.error.HTTPError: HTTP Error 403: Forbidden
. Itu sebabnya, ada kemungkinan skrip berperan sebagai sesuatu yang lain: dengan menentukan header HTTP saat mengunduh file.
Gunakan opsi http_headers
di file konfigurasi. Nilainya harus berupa objek kamus yang setiap headernya disajikan sebagai pasangan nilai kunci. Kuncinya adalah judul header dan nilainya adalah nilai header.
Secara default, nilainya adalah: {"User-Agent": "podcast-downloader"}
. Memberikan hal lain untuk http_headers
akan mengesampingkan semua nilai default (tidak digabungkan).
Di sisi lain dalam sub-konfigurasi podcast, http_headers
akan digabungkan dengan http_headers
global. Jika terjadi konflik (nama kunci yang sama), nilai dari sub-konfigurasi podcast akan menggantikan nilai global.
Contoh:
{
"http_headers" : {
"User-Agent" : " podcast-downloader "
},
"podcasts" : [
{
"name" : " Unua Podcast " ,
"rss_link" : " http://www.unuapodcast.org/feed.rss " ,
"path" : " ~/podcasts/unua_podcast " ,
"https_headers" : {
"User-Agent" : " Mozilla/5.0 "
}
},
{
"name" : " Dua Podcast " ,
"rss_link" : " http://www.duapodcast.org/feed.rss " ,
"path" : " ~/podcasts/dua_podcast " ,
"https_headers" : {
"Authorization" : " Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== "
}
}
]
}
Dalam contoh ini, Unua Podcast akan diunduh hanya dengan header: User-Agent: Mozilla/5.0
, dan Dua Podcast dengan: User-Agent: podcast-downloader
dan Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
.
Bila Anda memiliki banyak file untuk diunduh dari satu server, mungkin lebih baik mengatur jeda kecil di antara pengunduhan agar tidak dikenali sebagai penyerang oleh server. Di dalam skrip terdapat opsi bernama download_delay
, yang mewakili jumlah detik skrip akan menunggu di antara pengunduhan.
Nilai defaultnya adalah 0
.
Catatan:
Skrip menerima argumen baris perintah berikut:
Versi pendek | Nama panjang | Parameter | Bawaan | Catatan |
---|---|---|---|---|
--config | rangkaian | ~/.podcast_downloader_config.json | Penempatan file konfigurasi | |
--downloads_limit | nomor | ketakterbatasan | Jumlah maksimum file mp3 yang diunduh | |
--if_directory_empty | rangkaian | download_last | Pendekatan umum pada direktori kosong | |
--download_delay | nomor | 0 | Waktu tunggu (detik) antara pengunduhan |
Gunakan untuk menyesuaikan nama file setelah diunduh.
Nilai default ( %file_name%.%file_extension%
) akan dengan mudah menyimpan file seperti yang diunggah oleh pembuat aslinya. Nama file dan ekstensinya didasarkan pada link ke file podcast.
Nilai templat:
Nama | Catatan |
---|---|
%file_name% | Nama file dari link, tanpa ekstensi |
%file_extension% | Ekstensi file, dari link |
%publish_date% | Tanggal publikasi entri RSS |
%title% | Judul entri RSS |
%publish_date%
secara default memberikan hasil dalam format YEARMMDD
. Untuk mengubahnya Anda dapat memberikan yang baru setelah titik dua :
karakter :). Skripnya mengikuti kode standar C 1989, tetapi tanda persen ( %
) harus diganti dengan tanda dolar ( $
). Ini karena keputusan saya yang disayangkan untuk menggunakan karakter persen sebagai penanda kode.
Kode standar | Kode skrip | Catatan |
---|---|---|
%Y%m%d | $Y$m$d | Nilai default dari %publish_date% |
%A | $A | Menambahkan hari kerja (pengaturan bahasa lokal) |
%x | $x | Tanggal setempat mewakili. Peringatan : pada beberapa pengaturan, / digunakan di sini, sehingga mungkin menyebabkan masalah pada nama file |
[%publish_date%] %file_name%.%file_extension%
[%publish_date%] %title%.%file_extension%
Podcast sebagian besar disimpan sebagai file *.mp3
. Secara default, Pengunduh Podcast hanya mencarinya, mengabaikan semua jenis lainnya.
Jika podcast Anda mendukung jenis file media lain, Anda dapat menentukan filter file. Berikan ekstensi file (seperti .mp3
) dan jenis tautan di RSS feed itu sendiri (untuk mp3
adalah audio/mpeg
).
Jika Anda tidak mengetahui jenis filenya, Anda dapat mencarinya di file RSS. Carilah tag enclosure
, seharusnya terlihat seperti ini:
< enclosure url = " https://www.vidocast.url/podcast/episode23.m4a " length = " 14527149 " type = " audio/x-m4a " />
Catatan : titik pada ekstensi file diperlukan.
"podcast_extensions" : {
".mp3" : " audio/mpeg " ,
".m4a" : " audio/x-m4a "
}
Jika direktori untuk podcast kosong, skrip perlu mengetahui apa yang harus dilakukan. Karena kurangnya database, Anda dapat:
Perilaku defaultnya adalah: download_last
Skrip akan mengunduh semua episode dari feed.
Diatur oleh download_all_from_feed
.
Skrip hanya akan mengunduh episode terakhir dari feed. Ini juga merupakan pendekatan default skrip.
Diatur oleh download_last
.
Skrip akan mengunduh jumlah episode yang ditentukan dari feed.
Diatur oleh download_last_n_episodes
. N harus diganti dengan sejumlah episode yang ingin Anda unduh. Misalnya: download_last_5_episodes
berarti lima episode terbaru akan diunduh.
Skrip akan mengunduh semua episode yang muncul dalam n hari terakhir. Ini dapat digunakan saat Anda mengunduh dengan jadwal reguler. Nomor n diberikan dalam nilai pengaturan: download_from_n_days
. Misalnya: download_from_3_days
berarti mendownload semua episode dari 3 hari terakhir.
Skrip akan mengunduh semua episode yang muncul setelah hari rilis episode terakhir.
Angka n adalah hari episode normal. Anda dapat memberikan hari kerja di sini sebagai kata (ukuran huruf diabaikan)
Hari seminggu penuh | Persingkat nama |
---|---|
Senin | Senin |
Selasa | Selasa |
Rabu | Rabu |
Kamis | Kamis |
Jumat | Jumat |
Sabtu | Duduk |
Minggu | Matahari |
Anda dapat memberikan nomornya, itu berarti hari dalam sebulan. Skrip hanya menerima nomor dari 1 hingga 28.
Diatur oleh download_from_
.
Contoh:
Nilai contoh | Arti |
---|---|
download_from_monday | Episode baru muncul pada hari Senin. Script akan mendownload semua episode sejak Selasa lalu (termasuk itu) |
download_from_Fri | Episode baru muncul pada hari Jumat. Script akan mendownload semua episode sejak Sabtu lalu (termasuk itu) |
download_from_12 | Episode baru muncul setiap tanggal 12 setiap bulannya. Script akan mendownload semua episode sejak 13 bulan sebelumnya |
Setelah Anda membuat file totem, skrip dapat menggunakannya untuk menyimpan tanggal terakhir kali dijalankan. Kemudian, berdasarkan tanggal tersebut, skrip akan mengunduh semua episode baru yang muncul sejak saat itu.
Diatur oleh download_since_last_run
. Perlu membuat file penyimpanan dengan last_run_mark_file_path
.
{
"last_run_mark_file_path" : " ~/.totem.json " ,
"podcasts" : [
{
"name" : " The Skeptic Guide " ,
"rss_link" : " https://feed.theskepticsguide.org/feed/rss.aspx " ,
"path" : " ~/podcasts/SGTTU "
}
]
}
Script sedang membaca tanggal modifikasi terakhir file. Tanggal modifikasi file diperbarui oleh skrip.
Skrip mengenali aliran file yang diunduh (berdasarkan data feed). Secara default, file yang terakhir diunduh (menurut feed) menandai dimulainya pengunduhan. Jika terjadi kesenjangan, situasi di mana ada file yang hilang sebelum yang terakhir diunduh, skrip akan mengabaikannya secara default. Namun, ada kemungkinan untuk mengubah perilaku ini untuk mengunduh semua file yang hilang di antara file yang sudah diunduh. Untuk mengaktifkan ini, Anda perlu menyetel nilai fill_up_gaps
ke true . Penting untuk dicatat bahwa skrip tidak akan mengunduh file sebelum yang pertama (menurut feed), episode paling awal.
Nilai default: false
.
Skrip memeriksa semua node items
dalam file RSS. Node item
dapat berisi node enclosure
. Node tersebut digunakan untuk meneruskan file. Menurut konvensi, satu item
harus berisi hanya satu enclosure
, tetapi skrip (sebagai perpustakaan yang digunakan di bawahnya) dapat menangani banyak file yang dilampirkan ke item
podcast.
File OPML dapat dikonversi menjadi konfigurasi. File keluaran perlu disesuaikan (tidak ada path
).
import json
import sys
import xml . etree . ElementTree as ET
def build_podcast ( node_rss ):
return {
"name" : node_rss . attrib [ "title" ],
"rss_link" : node_rss . attrib [ "xmlUrl" ],
"path" : "" ,
}
tree = ET . parse ( sys . argv [ 1 ])
podcasts = list ( map ( build_podcast , tree . findall ( "body/outline[@type='rss']" )))
result = json . dumps ({ "podcasts" : podcasts }, sort_keys = True , indent = 4 )
print ( result )
Contoh penggunaan (setelah menyimpannya sebagai opml_converter.py
):
python opml_converter.py example.opml > podcast_downloader_config.json