summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Johnson <gavinj1984@gmail.com>2023-01-28 09:26:16 -0800
committerGavin Johnson <gavinj1984@gmail.com>2023-01-28 09:26:16 -0800
commit96344f28b4b842e915325aef64bc93fc9fc55387 (patch)
tree8e3824418387cd8eabb1ce6f52b8d0115c66d4af
parent855202e40e09af1cb5fb372d4a2d05a61b3a9bb2 (diff)
downloadinvidious-96344f28b4b842e915325aef64bc93fc9fc55387.tar.gz
invidious-96344f28b4b842e915325aef64bc93fc9fc55387.tar.bz2
invidious-96344f28b4b842e915325aef64bc93fc9fc55387.zip
added youtube playlist import functionality. fixes issue #2114
Signed-off-by: Gavin Johnson <gavinj1984@gmail.com>
-rw-r--r--locales/en-US.json2
-rw-r--r--src/invidious/routes/preferences.cr10
-rw-r--r--src/invidious/user/imports.cr123
-rw-r--r--src/invidious/views/feeds/playlists.ecr13
-rw-r--r--src/invidious/views/user/data_control.ecr4
5 files changed, 83 insertions, 69 deletions
diff --git a/locales/en-US.json b/locales/en-US.json
index c30a90db..8f1ec58d 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -33,7 +33,7 @@
"Import": "Import",
"Import Invidious data": "Import Invidious JSON data",
"Import YouTube subscriptions": "Import YouTube/OPML subscriptions",
- "Import YouTube playlist": "Import YouTube playlist (.csv)",
+ "Import YouTube playlist (.csv)": "Import YouTube playlist (.csv)",
"Import FreeTube subscriptions (.db)": "Import FreeTube subscriptions (.db)",
"Import NewPipe subscriptions (.json)": "Import NewPipe subscriptions (.json)",
"Import NewPipe data (.zip)": "Import NewPipe data (.zip)",
diff --git a/src/invidious/routes/preferences.cr b/src/invidious/routes/preferences.cr
index 570cba69..adac0068 100644
--- a/src/invidious/routes/preferences.cr
+++ b/src/invidious/routes/preferences.cr
@@ -310,6 +310,16 @@ module Invidious::Routes::PreferencesRoute
response: error_template(415, "Invalid subscription file uploaded")
)
end
+ # Gavin Johnson (thtmnisamnstr), 20230127: Call the Youtube playlist import function
+ when "import_youtube_pl"
+ filename = part.filename || ""
+ success = Invidious::User::Import.from_youtube_pl(user, body, filename, type)
+
+ if !success
+ haltf(env, status_code: 415,
+ response: error_template(415, "Invalid playlist file uploaded")
+ )
+ end
when "import_freetube"
Invidious::User::Import.from_freetube(user, body)
when "import_newpipe_subscriptions"
diff --git a/src/invidious/user/imports.cr b/src/invidious/user/imports.cr
index 870d083e..fa1bbe7f 100644
--- a/src/invidious/user/imports.cr
+++ b/src/invidious/user/imports.cr
@@ -30,73 +30,70 @@ struct Invidious::User
return subscriptions
end
- # Parse a youtube CSV playlist file and create the playlist
- #NEW - Done
+ # Gavin Johnson (thtmnisamnstr), 20230127: Parse a youtube CSV playlist file and create the playlist
def parse_playlist_export_csv(user : User, csv_content : String)
- rows = CSV.new(csv_content, headers: false)
- if rows.size >= 2
- title = rows[1][4]?.try &.as_s?.try
- descripton = rows[1][5]?.try &.as_s?.try
- visibility = rows[1][6]?.try &.as_s?.try
-
- if visibility.compare("Public", case_insensitive: true) == 0
- privacy = PlaylistPrivacy:Public
- else
- privacy = PlaylistPrivacy:Private
- end
+ rows = CSV.new(csv_content, headers: true)
+ row_counter = 0
+ playlist = uninitialized InvidiousPlaylist
+ title = uninitialized String
+ description = uninitialized String
+ visibility = uninitialized String
+ rows.each do |row|
+ if row_counter == 0
+ title = row[4]
+ description = row[5]
+ visibility = row[6]
+
+ if visibility.compare("Public", case_insensitive: true) == 0
+ privacy = PlaylistPrivacy::Public
+ else
+ privacy = PlaylistPrivacy::Private
+ end
+
+ if title && privacy && user
+ playlist = create_playlist(title, privacy, user)
+ end
+
+ if playlist && description
+ Invidious::Database::Playlists.update_description(playlist.id, description)
+ end
- if title && privacy && user
- playlist = create_playlist(title, privacy, user)
+ row_counter += 1
end
-
- if playlist && descripton
- Invidious::Database::Playlists.update_description(playlist.id, description)
+ if row_counter > 0 && row_counter < 3
+ row_counter += 1
end
- end
+ if row_counter >= 3
+ if playlist
+ video_id = row[0]
+ row_counter += 1
+ next if !video_id
- return playlist
- end
+ begin
+ video = get_video(video_id)
+ rescue ex
+ next
+ end
- # Parse a youtube CSV playlist file and add videos from it to a playlist
- #NEW - done
- def parse_playlist_videos_export_csv(playlist : Playlist, csv_content : String)
- rows = CSV.new(csv_content, headers: false)
- if rows.size >= 5
- offset = env.params.query["index"]?.try &.to_i? || 0
- row_counter = 0
- rows.each do |row|
- if row_counter >= 4
- video_id = row[0]?.try &.as_s?.try
- end
- row_counter += 1
- next if !video_id
+ playlist_video = PlaylistVideo.new({
+ title: video.title,
+ id: video.id,
+ author: video.author,
+ ucid: video.ucid,
+ length_seconds: video.length_seconds,
+ published: video.published,
+ plid: playlist.id,
+ live_now: video.live_now,
+ index: Random::Secure.rand(0_i64..Int64::MAX),
+ })
- begin
- video = get_video(video_id)
- rescue ex
- next
+ Invidious::Database::PlaylistVideos.insert(playlist_video)
+ Invidious::Database::Playlists.update_video_added(playlist.id, playlist_video.index)
end
-
- playlist_video = PlaylistVideo.new({
- title: video.title,
- id: video.id,
- author: video.author,
- ucid: video.ucid,
- length_seconds: video.length_seconds,
- published: video.published,
- plid: playlist.id,
- live_now: video.live_now,
- index: Random::Secure.rand(0_i64..Int64::MAX),
- })
-
- Invidious::Database::PlaylistVideos.insert(playlist_video)
- Invidious::Database::Playlists.update_video_added(playlist.id, playlist_video.index)
end
-
- videos = get_playlist_videos(playlist, offset: offset)
end
-
- return videos
+
+ return playlist
end
# -------------------
@@ -218,20 +215,20 @@ struct Invidious::User
return true
end
- # Import playlist from Youtube
- # Returns success status
- #NEW
+ # Gavin Johnson (thtmnisamnstr), 20230127: Import playlist from Youtube export. Returns success status.
def from_youtube_pl(user : User, body : String, filename : String, type : String) : Bool
extension = filename.split(".").last
if extension == "csv" || type == "text/csv"
playlist = parse_playlist_export_csv(user, body)
- playlist = parse_playlist_videos_export_csv(playlist, body)
+ if playlist
+ return true
+ else
+ return false
+ end
else
return false
end
-
- return true
end
# -------------------
diff --git a/src/invidious/views/feeds/playlists.ecr b/src/invidious/views/feeds/playlists.ecr
index a59344c4..05a48ce3 100644
--- a/src/invidious/views/feeds/playlists.ecr
+++ b/src/invidious/views/feeds/playlists.ecr
@@ -5,14 +5,21 @@
<%= rendered "components/feed_menu" %>
<div class="pure-g h-box">
- <div class="pure-u-2-3">
+ <div class="pure-u-1-3">
<h3><%= translate(locale, "user_created_playlists", %(<span id="count">#{items_created.size}</span>)) %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:right">
- <h3>
+ <div class="pure-u-1-3">
+ <h3 style="text-align:center">
<a href="/create_playlist?referer=<%= URI.encode_www_form(referer) %>"><%= translate(locale, "Create playlist") %></a>
</h3>
</div>
+ <div class="pure-u-1-3">
+ <h3 style="text-align:right">
+ <a href="/data_control?referer=<%= URI.encode_www_form(referer) %>">
+ <%= translate(locale, "Import/export") %>
+ </a>
+ </h3>
+ </div>
</div>
<div class="pure-g">
diff --git a/src/invidious/views/user/data_control.ecr b/src/invidious/views/user/data_control.ecr
index 0f8e8dae..27654b40 100644
--- a/src/invidious/views/user/data_control.ecr
+++ b/src/invidious/views/user/data_control.ecr
@@ -8,7 +8,7 @@
<legend><%= translate(locale, "Import") %></legend>
<div class="pure-control-group">
- <label for="import_youtube"><%= translate(locale, "Import Invidious data") %></label>
+ <label for="import_invidious"><%= translate(locale, "Import Invidious data") %></label>
<input type="file" id="import_invidious" name="import_invidious">
</div>
@@ -22,7 +22,7 @@
</div>
<div class="pure-control-group">
- <label for="import_youtube_pl"><%= translate(locale, "Import YouTube playlists") %></label>
+ <label for="import_youtube_pl"><%= translate(locale, "Import YouTube playlist (.csv)") %></label>
<input type="file" id="import_youtube_pl" name="import_youtube_pl">
</div>