mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-09-24 23:12:34 +08:00
feat(route): add vimeo with more (#7604)
* add vimeo with more * refactor: migrate to v2 Co-authored-by: TonyRL <TonyRL@users.noreply.github.com>
This commit is contained in:
@@ -336,6 +336,27 @@ This route requires Twitter token's corresponding id, therefore it's only availa
|
||||
|
||||
<RouteEn author="sakamossan" example="/twitter/trends/23424856" path="/twitter/trends/:woeid?" :paramsDesc="['Yahoo! Where On Earth ID. default to woeid=1 (World Wide)']" radar="1" rssbud="1"/>
|
||||
|
||||
## Vimeo
|
||||
|
||||
### User Profile
|
||||
|
||||
<RouteEn author="MisteryMonster" example="/vimeo/user/filmsupply/picks" path="/vimeo/user/:username/:cat?" :paramsDesc="['In this example [https://vimeo.com/filmsupply](https://vimeo.com/filmsupply) is `filmsupply`', 'deafult for all latest videos, others categories in this example such as `Docmentary`, `Narrative`, `Drama`. Set `picks` for promote orders, just orderd like web page. When `picks` added, published date won\'t show up']">
|
||||
::: tip Special category name attention
|
||||
|
||||
Some of the categories contain slash like `3D/CG` , must change the slash `/` to the vertical bar`|`.
|
||||
|
||||
:::
|
||||
|
||||
</RouteEn>
|
||||
|
||||
### Channel
|
||||
|
||||
<RouteEn author="MisteryMonster" example="/vimeo/channel/bestoftheyear" path="/vimeo/channel/:channel" :paramsDesc="['channel name can get from url like `bestoftheyear` in [https://vimeo.com/channels/bestoftheyear/videos](https://vimeo.com/channels/bestoftheyear/videos) .']" radar="1"/>
|
||||
|
||||
### Category
|
||||
|
||||
<RouteEn author="MisteryMonster" example="/vimeo/category/documentary/staffpicks" path="/vimeo/category/:category/:staffpicks?" :paramsDesc="['Category name can get from url like `documentary` in [https://vimeo.com/categories/documentary/videos](https://vimeo.com/categories/documentary/videos) ', 'type `staffpicks` to sort with staffpicks']" radar="1"/>
|
||||
|
||||
## YouTube
|
||||
|
||||
::: tip Tiny Tiny RSS users please notice
|
||||
|
||||
@@ -695,6 +695,32 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性
|
||||
|
||||
<Route author="sakamossan" example="/twitter/trends/23424856" path="/twitter/trends/:woeid?" :paramsDesc="['Where On Earth ID. 默认 woeid=1 (World Wide)']" radar="1" rssbud="1"/>
|
||||
|
||||
## Vimeo
|
||||
|
||||
### 用户页面
|
||||
|
||||
<Route author="MisteryMonster" example="/vimeo/user/filmsupply/picks" path="/vimeo/user/:username/:cat" :paramsDesc="['用户名或者 uid,用户名可从地址栏获得,如 [https://vimeo.com/filmsupply](https://vimeo.com/filmsupply) 中为 `filmsupply`', '分类根据不同的用户页面获得,例子中有`Docmentary`,`Narrative`,`Drama`等。填入 `picks` 为和首页一样的推荐排序,推荐排序下没有发布时间信息']" radar="1">
|
||||
|
||||
::: tip 请注意带有斜杠的的标签名
|
||||
|
||||
如果分类名带有斜杠符号的如 `3D/CG` 时,必须把斜杠`/`转成 `|`
|
||||
|
||||
:::
|
||||
|
||||
</Route>
|
||||
|
||||
### 频道页面
|
||||
|
||||
<Route author="MisteryMonster" example="/vimeo/channel/bestoftheyear" path="/vimeo/channel/:channel" :paramsDesc="['channel 名可从 url 获得,如 [https://vimeo.com/channels/bestoftheyear/videos](https://vimeo.com/channels/bestoftheyear/videos) 中的 `bestoftheyear`']" radar="1">
|
||||
|
||||
</Route>
|
||||
|
||||
### 分类页面
|
||||
|
||||
<Route author="MisteryMonster" example="/vimeo/category/documentary/staffpicks" path="/vimeo/category/:category/:staffpicks?" :paramsDesc="['主分类名可从 url 获得,如 [https://vimeo.com/categories/documentary/videos](https://vimeo.com/categories/documentary/videos) 中的 `documentary`。', '填入 `staffpicks` 则按 staffpicks 排序']" radar="1">
|
||||
|
||||
</Route>
|
||||
|
||||
## VueVlog
|
||||
|
||||
### 用户
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { category, staffpicks } = ctx.params;
|
||||
|
||||
const categoryparams = category;
|
||||
let sortparams = '&direction=desc&sort=date';
|
||||
let feedtitle = category;
|
||||
if (staffpicks && staffpicks !== 'staffpicks') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (staffpicks) {
|
||||
sortparams += '&filter=conditional_featured';
|
||||
feedtitle += `: ${category} staffpicks`;
|
||||
}
|
||||
|
||||
const url = `https://api.vimeo.com/categories/${categoryparams}/videos?page=1&per_page=18${sortparams}`;
|
||||
const tokenresponse = await got({
|
||||
method: 'get',
|
||||
url: 'https://vimeo.com/_rv/viewer',
|
||||
});
|
||||
const VimeoAuthorization = tokenresponse.data.jwt;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `jwt ${VimeoAuthorization}`,
|
||||
},
|
||||
});
|
||||
|
||||
const vimeojs = response.data.data;
|
||||
|
||||
const feedlink = `https://vimeo.com/categories/${category}/videos/sort:latest`;
|
||||
const feedlinkstaffpicks = '?staffpicked=ture';
|
||||
const feedDescription = await ctx.cache.tryGet(feedlink + (staffpicks ? feedlinkstaffpicks : ''), async () => {
|
||||
const response = await got({
|
||||
url: feedlink + (staffpicks ? feedlinkstaffpicks : ''),
|
||||
});
|
||||
const description = cheerio.load(response.data);
|
||||
return description('meta[name="description"]').attr('content');
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${feedtitle} | Vimeo category`,
|
||||
link: feedlink + (staffpicks ? feedlinkstaffpicks : ''),
|
||||
description: feedDescription,
|
||||
item: vimeojs.map((item) => ({
|
||||
title: item.name,
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
videoUrl: item.uri.replace(`/videos`, ''),
|
||||
vdescription: item.description ? item.description : '',
|
||||
}),
|
||||
pubDate: parseDate(item.created_time),
|
||||
link: item.link,
|
||||
author: item.user.name,
|
||||
})),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const channel = ctx.params.channel;
|
||||
const url = `https://vimeo.com/channels/${channel}/videos`;
|
||||
const page1 = await got({
|
||||
method: 'get',
|
||||
url: `${url}/page:1/sort:date/format:detail`,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
},
|
||||
});
|
||||
const page2 =
|
||||
channel === `bestoftheyear`
|
||||
? await got({
|
||||
method: 'get',
|
||||
url: `${url}/page:2/sort:date/format:detail`,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
},
|
||||
})
|
||||
: '';
|
||||
const pagedata = page1.data.concat(page2.data);
|
||||
const $ = cheerio.load(pagedata);
|
||||
const list = $('ol li.clearfix');
|
||||
|
||||
const description = await Promise.all(
|
||||
list.get().map((item) => {
|
||||
item = $(item);
|
||||
const link = item.find('.more').attr('href');
|
||||
return ctx.cache.tryGet(link, async () => {
|
||||
const response2 = await got({
|
||||
method: 'get',
|
||||
url: `https://vimeo.com${link}/description?breeze=1`,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) ',
|
||||
},
|
||||
});
|
||||
const articledata = response2.data;
|
||||
const $2 = cheerio.load(articledata);
|
||||
$2('span').remove();
|
||||
return $2.html();
|
||||
});
|
||||
})
|
||||
);
|
||||
ctx.state.data = {
|
||||
title: `${channel} | Vimeo channel`,
|
||||
link: url,
|
||||
item: list
|
||||
.map((index, item) => {
|
||||
item = $(item);
|
||||
const title = item.find('.title a').text();
|
||||
const author = item.find('.meta a').text();
|
||||
return {
|
||||
title,
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
videoUrl: item.find('.more').attr('href'),
|
||||
vdescription: description[index] ? description[index] : '',
|
||||
}),
|
||||
pubDate: parseDate(item.find('time').attr('datetime')),
|
||||
link: `https://vimeo.com${item.find('.more').attr('href')}`,
|
||||
author,
|
||||
};
|
||||
})
|
||||
.get(),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
module.exports = {
|
||||
'vimeo.com': {
|
||||
_name: 'Vimeo',
|
||||
'.': [
|
||||
{
|
||||
title: 'User videos',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#vimeo-yong-hu-ye-mian',
|
||||
source: '/:username/',
|
||||
target: (params, url, document) => {
|
||||
const uid = document && document.querySelector('html').innerHTML.match(/app.vimeo.com\/users\/([0-9]+)/)[1];
|
||||
return uid ? `/vimeo/user/${uid}` : '';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'User Video Category',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#vimeo-yong-hu-ye-mian',
|
||||
source: '/',
|
||||
},
|
||||
{
|
||||
title: 'Channel',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#vimeo-channel',
|
||||
source: ['/channels/:channel', '/channels/:channel/videos', '/channels/:channel/videos/:sort/:format'],
|
||||
target: '/vimeo/channel/:channel',
|
||||
},
|
||||
{
|
||||
title: 'Category',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#vimeo-category',
|
||||
source: ['/categories/:category', '/categories/:category/:subcategory', '/categories/:category/:subcategory/videos'],
|
||||
target: (params) => `/vimeo/category/:category${params.subcategory ? `/` + params.subcategory : ''}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/category/:category/:staffpicks?', require('./category'));
|
||||
router.get('/channel/:channel', require('./channel'));
|
||||
router.get('/user/:username/:cat?', require('./usr-videos'));
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
<iframe width="640" height="360" src="https://player.vimeo.com/video{{ videoUrl }}" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
|
||||
{{ if vdescription }}
|
||||
<p>{{@ vdescription }}</p>
|
||||
{{ /if }}
|
||||
@@ -0,0 +1,76 @@
|
||||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const tokenresponse = await got({
|
||||
method: 'get',
|
||||
url: 'https://vimeo.com/_rv/viewer',
|
||||
});
|
||||
const VimeoAuthorization = tokenresponse.data.jwt;
|
||||
|
||||
const { username, cat } = ctx.params;
|
||||
|
||||
const profileresponse = await got({
|
||||
method: 'get',
|
||||
url: `https://api.vimeo.com/users/${username}?fields=name,gender,bio,uri,link,categories&fetch_user_profile=1`,
|
||||
headers: {
|
||||
Authorization: `jwt ${VimeoAuthorization}`,
|
||||
},
|
||||
});
|
||||
|
||||
const profilesjs = profileresponse.data;
|
||||
const catjs = profileresponse.data.categories;
|
||||
|
||||
let catword;
|
||||
if (cat && catjs.length > 0) {
|
||||
for (let s = 0; s < catjs.length; s++) {
|
||||
if (decodeURIComponent(cat).replace('|', '/') === catjs[s].name) {
|
||||
catword = catjs[s].word;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let urlfilter = `&filter=category&filter_category=${catword}`;
|
||||
if (!cat) {
|
||||
urlfilter = '';
|
||||
}
|
||||
if (!catword && cat && cat !== 'picks') {
|
||||
return '';
|
||||
}
|
||||
const picked = cat && cat === 'picks';
|
||||
|
||||
const Vimeocat = `${profilesjs.uri}/videos?fields=name,uri,description,created_time&include_videos=1&page=1&per_page=10${urlfilter}`;
|
||||
const Vimeoallpicks = `/users/${username}/profile_sections?fields=videos.data.clip.name,videos.data.clip.uri,videos.data.clip.description,videos.data.clip.created_time&include_videos=1&badge=1&page=1&per_page=10`;
|
||||
|
||||
const contentresponse = await got({
|
||||
method: 'get',
|
||||
url: `https://api.vimeo.com${picked ? Vimeoallpicks : Vimeocat}`,
|
||||
headers: {
|
||||
Authorization: `jwt ${VimeoAuthorization}`,
|
||||
},
|
||||
});
|
||||
const vimeojs = picked ? contentresponse.data.data[0].videos.data : contentresponse.data.data;
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${profilesjs.name} ${catword ? cat.replace('|', '/') : ''} ${picked ? 'picks' : ''} | Vimeo `,
|
||||
link: profilesjs.link,
|
||||
description: profilesjs.bio,
|
||||
|
||||
item: vimeojs.map((item) => {
|
||||
const vdescription = picked ? item.clip.description : item.description;
|
||||
|
||||
return {
|
||||
title: picked ? item.clip.name : item.name,
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
videoUrl: picked ? item.clip.uri.replace('/videos', '') : item.uri.replace('/videos', ''),
|
||||
vdescription: vdescription ? vdescription.replace(/\n/g, '<br>') : '',
|
||||
}),
|
||||
pubDate: parseDate(picked || cat ? '' : item.created_time),
|
||||
link: `https://vimeo.com${picked ? item.clip.uri.replace('videos/', '') : item.uri.replace('videos/', '')}`,
|
||||
author: profilesjs.name,
|
||||
};
|
||||
}),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user