通知
GeekApk 里,通知 作为一种对 用户 的提醒而存在,一般在 动作执行后 直接保存等待用户阅读,GeekApk 中有这些通知:
类似 GitHub,GeekApk 也会记录每个 用户 的公开活动并允许所有人自由查询,这个特性被称为 Timeline(时间线),GeekApk 中有这些时间线记录:
用户可按照跟随数目排序,这要在数据库表里增加
应用按照 Star 数、Comment 数、更新时间排序,这要在表里增加
评论只能按照创建时间排序
权限
权限还是用户可写,全服只有一个管理帐号使用
用户还是
计算密码的 Hash 值过程由客户端执行,所有官方客户端都自动取 Hash 值作为密码
简易模型
用户 |
用户可以跟随其他用户,用户有 metahash 和 hash,用户可以发布评论/应用/更新/星标
分类 |
管理员可以创建/删除分类、修改分类名
应用 |
应用可以被附加更新和评论,被用户星标
评论 |
评论可以被附加子评论
具体
用户有简易名称、用户名和不可修改的 UID、头像链接、介绍、创建时间、小黑屋状态
分类有自己不可修改的 ID 和名称,一般以
应用有不可修改的 ID(包名)、创建用户的 ID 引用、所属分类的 ID 引用、名称、图标链接、应用描述、预览图像、创建时间和更新时间
更新有所属应用的 ID 引用、版本名、reversion、安装链接、更新内容、最低和最高适配 SDK 版本
评论有不可修改的 ID、创建用户的 ID 引用、所属应用的 ID 引用、回复评论的 ID 引用、内容、创建时间和更新时间、被回复数
时间线有所属用户引用、创建时间、类型、数据引用
通知有所属用户、创建时间、类型、数据引用、已读状态
为了允许在用户和应用间创建 Star 关系、用户和用户之前创建跟随关系,还额外建立了
GeekApk 里,通知 作为一种对 用户 的提醒而存在,一般在 动作执行后 直接保存等待用户阅读,GeekApk 中有这些通知:
用户 的 评论 被 回复 的通知Timeline(时间线)
用户 被 @ 提到 的通知
用户 被 用户 跟随 的通知
类似 GitHub,GeekApk 也会记录每个 用户 的公开活动并允许所有人自由查询,这个特性被称为 Timeline(时间线),GeekApk 中有这些时间线记录:
用户 Follow 了某个 用户排序
用户 创建了 某个 评论
用户 更新了 某个 评论
用户 发布了 某个 应用
用户 发布了 某个 应用 的 更新
用户 删除了 某个 应用
用户 Star 了某个 应用
用户可按照跟随数目排序,这要在数据库表里增加
followers_num 字段应用按照 Star 数、Comment 数、更新时间排序,这要在表里增加
stars_num 和 comments_num 字段评论只能按照创建时间排序
权限
权限还是用户可写,全服只有一个管理帐号使用
DOGE_TOK 验证,只行使管理员权限而没有用户权限用户还是
uid 和 hash 两个 cookie、分发密码称为 metahash.计算密码的 Hash 值过程由客户端执行,所有官方客户端都自动取 Hash 值作为密码
简易模型
用户 |
user | users | uid | GeekApk 用户帐号用户可以跟随其他用户,用户有 metahash 和 hash,用户可以发布评论/应用/更新/星标
分类 |
category | categories | tid | GeekApk 应用分类管理员可以创建/删除分类、修改分类名
应用 |
app | apps | aid | GeekApk 应用应用可以被附加更新和评论,被用户星标
评论 |
comment | comments | cid | GeekApk 评论评论可以被附加子评论
具体
用户有简易名称、用户名和不可修改的 UID、头像链接、介绍、创建时间、小黑屋状态
分类有自己不可修改的 ID 和名称,一般以
/ 切分路径应用有不可修改的 ID(包名)、创建用户的 ID 引用、所属分类的 ID 引用、名称、图标链接、应用描述、预览图像、创建时间和更新时间
更新有所属应用的 ID 引用、版本名、reversion、安装链接、更新内容、最低和最高适配 SDK 版本
评论有不可修改的 ID、创建用户的 ID 引用、所属应用的 ID 引用、回复评论的 ID 引用、内容、创建时间和更新时间、被回复数
时间线有所属用户引用、创建时间、类型、数据引用
通知有所属用户、创建时间、类型、数据引用、已读状态
为了允许在用户和应用间创建 Star 关系、用户和用户之前创建跟随关系,还额外建立了
follow 和 star 表傲梦 OJ 相关的 API(貌似是自己写的,要不然不会连 Vue.js 开发模式都没关(这次我再找到有啥问题不会发邮件通知他们了,发了也没好脸色看)👎
GET https://all-dream.com/napi/cfxy/questions
获得试题组,返回一个 JSON 列表,每个试题看起来是这样的:
获得小类(题类)组,大类下面是小类,小类下面是题目,返回数组
获得大类列表,每个大类对象看起来像这样
GET/POST https://all-dream.com/napi/cfxy/runlog?userId=uid
返回 uid 的运行记录题目 ID JSON 列表
尝试运行代码
POST https://all-dream.com/napi/cfxy/runcode
参数 code、questionId、userId
GET https://all-dream.com/napi/cfxy/questions
获得试题组,返回一个 JSON 列表,每个试题看起来是这样的:
{
"id": 16,
"name": "造梯子",
"description": "见惯了生活中的木梯子、石梯子,你见过用*造的梯子吗?那么现在尝试去造一个*做的梯子吧!\r\n\r\n注:每两个相邻的\"*\"之间用一个空格隔开,且每行没有多余的空格。",
"chapter_id": "0636f9bc-aff3-4bed-b38d-ab1242d4a88d",
"reward": 1,
"create_time": "2016-04-29T11:05:01.000Z",
"intput": "无",
"output": "*\r\n**\r\n***",
"example_input": "无",
"example_output": "*\r\n**\r\n***",
"tips": "printf结合\\n的使用",
"attempt": 511,
"pass": 420,
"time_limit": 1000,
"test_time_limit": 1000,
"memory_limit": 50,
"in_file_path": "",
"out_file_path": "ONLINETEST/6da99376-3237-4b5a-b991-e6e1b8e08382/1.out,",
"sort_num": 1,
"oss": "6da99376-3237-4b5a-b991-e6e1b8e08382"
}
GET https://all-dream.com/napi/cfxy/chapters获得小类(题类)组,大类下面是小类,小类下面是题目,返回数组
{
"id": "0636f9bc-aff3-4bed-b38d-ab1242d4a88d",
"name": "C1. 输出",
"group_id": "7fbcb3aa-da34-455e-ac75-6fcee72ed2f3",
"description": "输出",
"create_time": "2016-04-29T10:31:55.000Z",
"attempt": 557,
"pass": 78,
"sort_num": 1
}
GET https://all-dream.com/napi/cfxy/group获得大类列表,每个大类对象看起来像这样
{
"id": "7fbcb3aa-da34-455e-ac75-6fcee72ed2f3",
"name": "C语言",
"description": "",
"sort_num": 1
}
获得运行记录GET/POST https://all-dream.com/napi/cfxy/runlog?userId=uid
返回 uid 的运行记录题目 ID JSON 列表
尝试运行代码
POST https://all-dream.com/napi/cfxy/runcode
参数 code、questionId、userId
响应 JSON 包含 id(qid)、code、ret JSON({"info": [{"cpu_time": 1, "exit_status": 0, "signal": 0, "real_time": 2, "flag": 0, "result": 6, "memory": 22884352, "output": "", "message": "\u5b9e\u9645\u8f93\u51fa\u548c\u671f\u671b\u8f93\u51fa\u4e0d\u4e00\u81f4"}], "result": 6})JavaScript 版本
function runlog(uid, fun) {
var req = new XMLHttpRequest();
req.addEventListener('load', fun);
req.open('POST', 'https://all-dream.com/napi/cfxy/runlog');
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send('userId=' + uid);
return req;
}function runlog(uid, fun) {
var request = require("request");
return request({
uri: "https://all-dream.com/napi/cfxy/runlog",
method: "POST",
form: {
userId: uid
}
}, function(error, response, body) {
fun(JSON.parse(body));
});
}
runlog('d21ad8f718264854a4dee4dc4a11badd', console.log)function runcode(uid, qid, code, fun) {
var request = require("request");
return request({
uri: "https://all-dream.com/napi/cfxy/runcode",
method: "POST",
form: {
userId: uid, questionId: qid, code: code
}
}, function(error, response, body) {
fun(JSON.parse(body));
});
}
runcode('d21ad8f718264854a4dee4dc4a11badd', 18, '', console.log)function runlogPromise(uid) {
var request = require("request");
return new Promise((resolve, reject) => {
request({ uri: 'https://all-dream.com/napi/cfxy/runlog', method: 'POST', form: { userId: uid } },
(err, resp, body) => {
if (err) { reject(err) } else { resolve(JSON.parse(body)); }
});
});
}
runlogPromise('d21ad8f718264854a4dee4dc4a11badd').then(console.log)上次不待见我,这次 OJ 不验证权限的事情就不跟他们说了,反正也不在乎嘛,我自己来跑一个全国 20000+ 用户的做题情况数据统计分析
我早就可以在他们完全不知情的情况下拖下来全部用户的信息,都可以卖到哪个艺术家上广场展览了,这么严重而且幼稚的问题我还替他们擦屁股,不如直接拖下来卖了