Skip to content

Commit

Permalink
Merge pull request #762 from DIYgod/master
Browse files Browse the repository at this point in the history
[pull] master from diygod:master
  • Loading branch information
pull[bot] authored Jan 27, 2023
2 parents 82a0bdb + e90afcb commit 1da7edf
Show file tree
Hide file tree
Showing 16 changed files with 1,834 additions and 70 deletions.
12 changes: 12 additions & 0 deletions docs/en/multimedia.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,18 @@ See [Directory](https://www.javlibrary.com/en/star_list.php) to view all stars.

</RouteEn>

## Mixcloud

### User

<RouteEn author="Misaka13514" example="/mixcloud/dholbach/uploads" path="/mixcloud/:username/:type?" :paramsDesc="['Username, can be found in URL', 'Type, see below, uploads by default']" radar="1" rssbud="1" supportPodcast="1">

| Shows | Favorites | History | Stream |
| ------- | --------- | ------- | ------ |
| uploads | favorites | listens | stream |

</RouteEn>

## Nyaa

### Search Result
Expand Down
12 changes: 12 additions & 0 deletions docs/multimedia.md
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,18 @@ JavDB 有多个备用域名,本路由默认使用永久域名 <https://javdb.c

</Route>

## Mixcloud

### 用户

<Route author="Misaka13514" example="/mixcloud/dholbach/uploads" path="/mixcloud/:username/:type?" :paramsDesc="['用户名,可在对应用户页 URL 中找到', '分类,见下表,默认为 uploads']" radar="1" rssbud="1" supportPodcast="1">

| Shows | Favorites | History | Stream |
| ------- | --------- | ------- | ------ |
| uploads | favorites | listens | stream |

</Route>

## Mp4Ba

### 影视分类
Expand Down
10 changes: 5 additions & 5 deletions docs/new-media.md
Original file line number Diff line number Diff line change
Expand Up @@ -3423,15 +3423,15 @@ column 为 third 时可选的 category:

### 分类

<Route author="nczitzk" example="/ruancan/sort/news" path="/ruancan/sort/:sort" :paramsDesc="['分类 id,可在对应分类页 URL 中找到']"/>
<Route author="nczitzk" example="/ruancan/category/news" path="/ruancan/category/:category?" :paramsDesc="['分类 id,可在对应分类页 URL 中找到,默认为业界']"/>

### 标签
### 搜索

<Route author="nczitzk" example="/ruancan/tag/oxygenos" path="/ruancan/tag/:tag" :paramsDesc="['标签 id,可在对应标签页 URL 中找到']"/>
<Route author="nczitzk" example="/ruancan/search/Windows" path="/ruancan/search/:keyword?" :paramsDesc="['关键字,默认为空']"/>

### 搜索
### 用户文章

<Route author="nczitzk" example="/ruancan/search/ColorOS" path="/ruancan/search/:keyword?" :paramsDesc="['关键字,默认为空']"/>
<Route author="nczitzk" example="/ruancan/user/72" path="/ruancan/user/:id?" :paramsDesc="['用户 id,可在对应用户页 URL 中找到']"/>

## 上下游 News\&Market

Expand Down
130 changes: 130 additions & 0 deletions lib/v2/mixcloud/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const got = require('@/utils/got');
const CryptoJS = require('crypto-js');
const { parseDate } = require('@/utils/parse-date');
const { queries } = require('./queries');

module.exports = async (ctx) => {
const host = 'https://www.mixcloud.com';
const imageBaseURL = 'https://thumbnailer.mixcloud.com/unsafe/480x480/';
const headers = {
Referer: host,
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
};

const type = ctx.params.type ?? 'uploads';
if (!['stream', 'uploads', 'favorites', 'listens'].includes(type)) {
throw Error(`Invalid type: ${type}`);
}
const username = ctx.params.username;

const config = {
stream: { name: 'Stream', node: 'stream' },
uploads: { name: 'Shows', node: 'uploads' },
favorites: { name: 'Favorites', node: 'favorites' },
listens: { name: 'History', node: 'listeningHistory' },
};
const payloads = {
stream: {
query: queries.stream.query,
variables: {
lookup: {
username: ctx.params.username,
},
},
},
uploads: {
query: queries.uploads.query,
variables: {
lookup: {
username: ctx.params.username,
},
orderBy: 'LATEST',
audioTypes: ['SHOW'],
},
},
favorites: {
query: queries.favorites.query,
variables: {
lookup: {
username: ctx.params.username,
},
},
},
listens: {
query: queries.listens.query,
variables: {
lookup: {
username: ctx.params.username,
},
},
},
profile: {
query: queries.profile.query,
variables: {
lookup: {
username: ctx.params.username,
},
},
},
};

const profile = (
await got({
method: 'post',
url: `${host}/graphql`,
json: payloads.profile,
headers,
})
).data.data;

const biog = profile.user.biog;
const image = `${imageBaseURL}${profile.user.picture.urlRoot}`;

const data = (
await got({
method: 'post',
url: `${host}/graphql`,
json: payloads[type],
headers,
})
).data.data;

// https://github.com/ytdl-org/youtube-dl/blob/f1487d4fca40fd37d735753e24a7bae53a1b1513/youtube_dl/extractor/mixcloud.py#L72-L79
const decryptionKey = 'IFYOUWANTTHEARTISTSTOGETPAIDDONOTDOWNLOADFROMMIXCLOUD';
const decryptXorCipher = (key, cipherText) => {
const cipher = CryptoJS.enc.Base64.parse(cipherText);
const decrypted = cipher.toString(CryptoJS.enc.Utf8);
let result = '';
for (let i = 0; i < decrypted.length; i++) {
result += String.fromCharCode(decrypted.charCodeAt(i) ^ key.charCodeAt(i % key.length));
}
return result;
};

const items = data.user[config[type].node].edges.map((edge) => {
const item = type === 'listens' ? edge.node.cloudcast : edge.node;
return {
title: item.name,
author: item.owner.displayName,
description: item.description.replace(/\n/g, '<br>'),
pubDate: parseDate(item.publishDate),
guid: Buffer.from(item.id, 'base64').toString('utf8'),
link: `${host}/${username}/${item.slug}`,
itunes_item_image: `${imageBaseURL}${item.picture.urlRoot}`,
itunes_duration: item.audioLength,
enclosure_url: decryptXorCipher(decryptionKey, item.streamInfo.url),
enclosure_type: 'audio/x-m4a',
upvotes: item.favorites.totalCount,
};
});

ctx.state.data = {
title: `Mixcloud - ${data.user.displayName}'s ${config[type].name}`,
description: biog.replace(/\n/g, '<br>'),
itunes_author: data.user.displayName,
image,
link: `${host}/${username}/${type}/`,
item: items,
};
};
3 changes: 3 additions & 0 deletions lib/v2/mixcloud/maintainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
'/:username/:type?': ['Misaka13514'],
};
Loading

1 comment on commit 1da7edf

@vercel
Copy link

@vercel vercel bot commented on 1da7edf Jan 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.