yd: Use yt-dlp instead of youtube-dl
[sunny256-utils.git] / ydid
blob518e64e71f254c94ce1f98ef136140f66eea4755
1 #!/usr/bin/env perl
3 #==============================================================================
4 # ydid
5 # File ID: 533a9d38-23d9-11e9-ac41-4f45262dc9b5
7 # [Description]
9 # Character set: UTF-8
10 # ©opyleft 2019– Øyvind A. Holm <sunny@sunbase.org>
11 # License: GNU General Public License version 2 or later, see end of file for
12 # legal stuff.
13 #==============================================================================
15 use strict;
16 use warnings;
17 use Getopt::Long;
19 local $| = 1;
21 our %Opt = (
23 'create-url' => 0,
24 'help' => 0,
25 'quiet' => 0,
26 'verbose' => 0,
27 'version' => 0,
31 our $progname = $0;
32 $progname =~ s/^.*\/(.*?)$/$1/;
33 our $VERSION = '0.2.2';
35 Getopt::Long::Configure('bundling');
36 GetOptions(
38 'create-url|c' => \$Opt{'create-url'},
39 'help|h' => \$Opt{'help'},
40 'quiet|q+' => \$Opt{'quiet'},
41 'verbose|v+' => \$Opt{'verbose'},
42 'version' => \$Opt{'version'},
44 ) || die("$progname: Option error. Use -h for help.\n");
46 $Opt{'verbose'} -= $Opt{'quiet'};
47 $Opt{'help'} && usage(0);
48 if ($Opt{'version'}) {
49 print_version();
50 exit(0);
53 exit(main());
55 sub main {
56 my $id = '';
57 my $url = $ARGV[0];
59 defined($url) || myexit(1, "No URL specified");
61 $id = get_id($Opt{'create-url'}, $url);
62 print("$id\n");
64 return 0;
67 sub create_url {
68 my ($type, $id, $user) = @_;
70 if ($type eq "youtube") {
71 return "https://www.youtube.com/watch?v=$id";
72 } elsif ($type eq "twitter") {
73 return "https://twitter.com/$user/status/$id";
74 } else {
75 myexit(1, "Internal error: create_url(): $type: Unknown type");
79 sub get_id {
80 my ($create_url, $url) = @_;
81 my $id = '';
83 msg(2, "url = \"$url\"");
84 $url =~ s!^https?://!!;
85 $url =~ s/^www\.//;
86 $url =~ s/^m\.//;
88 if ($url =~ /^youtube\.com\/watch\?.*\bv=(.*)/) {
89 $id = $1;
90 msg(2, "Found youtube.com/watch?v=*");
91 $id =~ s/\&.*//;
92 valid_youtube_id($id) || myexit(1, "Invalid URL");
93 $create_url && ($id = create_url("youtube", $id));
94 } elsif ($url =~ /^youtu\.be\/(.*)/) {
95 $id = $1;
96 msg(2, "Found youtu.be/*");
97 $id =~ s/\&.*//;
98 valid_youtube_id($id) || myexit(1, "Invalid URL");
99 $create_url && ($id = create_url("youtube", $id));
100 } elsif ($url =~ /^twitter.com\/([^\/]+)\/status\/(\d+)/) {
101 my $user;
102 ($user, $id) = ($1, $2);
103 msg(2, "Found twitter.com/*/status/*");
104 valid_twitter_id($id) || myexit(1, "Invalid Twitter ID");
105 $create_url && ($id = create_url("twitter", $id, $user));
106 } elsif ($url =~ /^google\.com\/url.*\&url=(.+)/) {
107 $id = $1;
108 msg(2, "Found google.com/url*url=*");
109 $id =~ s/\&.*//;
110 $id = get_id(0, url2txt($id));
111 length($id) || myexit(1, "Invalid Google URL");
112 $Opt{'create-url'} && ($id = create_url("youtube", $id));
113 } elsif (length($url) == 11) {
114 msg(2, "Found plain id");
115 valid_youtube_id($url) || myexit(1, "Invalid Youtube ID");
116 $id = $create_url ? create_url("youtube", $url) : $url;
117 } else {
118 myexit(1, "Unknown URL format");
121 return $id;
124 sub url2txt {
125 my $txt = shift;
127 $txt =~ s/%([0-9a-f]{2})/chr(hex($1))/gei;
128 return $txt;
131 sub valid_twitter_id {
132 my $id = shift;
134 ($id =~ /\d/) || return 0;
135 ($id =~ /\D/) && return 0;
137 return 1;
140 sub valid_youtube_id {
141 my $id = shift;
142 my $ytchars = join('',
143 '\-' .
144 '0123456789' .
145 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
146 '_' .
147 'abcdefghijklmnopqrstuvwxyz'
150 if (length($id) != 11) {
151 return 0;
154 my $strid = $id;
155 $strid =~ s/[$ytchars]//g;
156 if (length($strid)) {
157 return 0;
160 return 1;
163 sub print_version {
164 # Print program version
165 print("$progname $VERSION\n");
166 return;
169 sub usage {
170 # Send the help message to stdout
171 my $Retval = shift;
173 if ($Opt{'verbose'}) {
174 print("\n");
175 print_version();
177 print(<<"END");
179 Usage: $progname [options] URL
181 Options:
183 -c, --create-url
184 Generate generic URL instead of ID and remove additional URL
185 parameters.
186 -h, --help
187 Show this help.
188 -q, --quiet
189 Be more quiet. Can be repeated to increase silence.
190 -v, --verbose
191 Increase level of verbosity. Can be repeated.
192 --version
193 Print version information.
196 exit($Retval);
199 sub msg {
200 # Print a status message to stderr based on verbosity level
201 my ($verbose_level, $Txt) = @_;
203 if ($Opt{'verbose'} >= $verbose_level) {
204 print(STDERR "$progname: $Txt\n");
206 return;
209 sub myexit {
210 my ($exitval, $msg) = @_;
212 print(STDERR "$progname: $msg\n");
213 exit($exitval);
216 __END__
218 # This program is free software; you can redistribute it and/or modify it under
219 # the terms of the GNU General Public License as published by the Free Software
220 # Foundation; either version 2 of the License, or (at your option) any later
221 # version.
223 # This program is distributed in the hope that it will be useful, but WITHOUT
224 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
225 # FOR A PARTICULAR PURPOSE.
226 # See the GNU General Public License for more details.
228 # You should have received a copy of the GNU General Public License along with
229 # this program.
230 # If not, see L<http://www.gnu.org/licenses/>.
232 # vim: set ts=8 sw=8 sts=8 noet fo+=w tw=79 fenc=UTF-8 :