ss

我们要改一下backendserver的service

因为要写几个api还要做很多操作

我们单独写出来 然后由service来调用

import json
import os
import pickle
import random
import redis
import sys from bson.json_util import dumps
from datetime import datetime # import common package in parent directory
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common')) import mongodb_client REDIS_HOST = "localhost"
REDIS_PORT = # NEWS_TABLE_NAME = "news"
NEWS_TABLE_NAME = "news-test"
CLICK_LOGS_TABLE_NAME = 'click_logs' NEWS_LIMIT =
NEWS_LIST_BATCH_SIZE =
USER_NEWS_TIME_OUT_IN_SECONDS = redis_client = redis.StrictRedis(REDIS_HOST, REDIS_PORT, db=) def getNewsSummariesForUser(user_id, page_num):
page_num = int(page_num)
begin_index = (page_num - ) * NEWS_LIST_BATCH_SIZE
end_index = page_num * NEWS_LIST_BATCH_SIZE # The final list of news to be returned.
sliced_news = [] if redis_client.get(user_id) is not None:
news_digests = pickle.loads(redis_client.get(user_id)) # If begin_index is out of range, this will return empty list;
# If end_index is out of range (begin_index is within the range), this
# will return all remaining news ids.
sliced_news_digests = news_digests[begin_index:end_index]
print sliced_news_digests
db = mongodb_client.get_db()
sliced_news = list(db[NEWS_TABLE_NAME].find({'digest':{'$in':sliced_news_digests}}))
else:
db = mongodb_client.get_db()
total_news = list(db[NEWS_TABLE_NAME].find().sort([('publishedAt', -)]).limit(NEWS_LIMIT))
total_news_digests = map(lambda x:x['digest'], total_news) redis_client.set(user_id, pickle.dumps(total_news_digests))
redis_client.expire(user_id, USER_NEWS_TIME_OUT_IN_SECONDS) sliced_news = total_news[begin_index:end_index] for news in sliced_news:
# Remove text field to save bandwidth.
del news['text']
if news['publishedAt'].date() == datetime.today().date():
news['time'] = 'today'
return json.loads(dumps(sliced_news))

operations.py

具体实现

可以自己设置这个过期时间

我们都是下拉获得新闻 你也可以设计一个向上拉强制刷新的功能 比如向上拉触发一个函数cleanRedis来强制清空redis(类似新浪知乎)这样 即使100条获取完了没得获取了

也能强制刷新列表(之后写吧)

import json
import os
import pickle
import random
import redis
import sys from bson.json_util import dumps
from datetime import datetime # import common package in parent directory
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common')) import mongodb_client REDIS_HOST = "localhost"
REDIS_PORT = # NEWS_TABLE_NAME = "news"
NEWS_TABLE_NAME = "news-test"
CLICK_LOGS_TABLE_NAME = 'click_logs' NEWS_LIMIT =
NEWS_LIST_BATCH_SIZE =
USER_NEWS_TIME_OUT_IN_SECONDS = redis_client = redis.StrictRedis(REDIS_HOST, REDIS_PORT, db=) def getNewsSummariesForUser(user_id, page_num):
page_num = int(page_num)
begin_index = (page_num - ) * NEWS_LIST_BATCH_SIZE
end_index = page_num * NEWS_LIST_BATCH_SIZE # The final list of news to be returned.
sliced_news = [] if redis_client.get(user_id) is not None:
news_digests = pickle.loads(redis_client.get(user_id)) # If begin_index is out of range, this will return empty list;
# If end_index is out of range (begin_index is within the range), this
# will return all remaining news ids.
sliced_news_digests = news_digests[begin_index:end_index]
print sliced_news_digests
db = mongodb_client.get_db()
sliced_news = list(db[NEWS_TABLE_NAME].find({'digest':{'$in':sliced_news_digests}}))
else:
db = mongodb_client.get_db()
total_news = list(db[NEWS_TABLE_NAME].find().sort([('publishedAt', -)]).limit(NEWS_LIMIT))
total_news_digests = map(lambda x:x['digest'], total_news) redis_client.set(user_id, pickle.dumps(total_news_digests))
redis_client.expire(user_id, USER_NEWS_TIME_OUT_IN_SECONDS) sliced_news = total_news[begin_index:end_index] for news in sliced_news:
# Remove text field to save bandwidth.
del news['text']
if news['publishedAt'].date() == datetime.today().date():
news['time'] = 'today'
return json.loads(dumps(sliced_news))

operations.py

上面代码提到的比如 lamda表达式配合map摘取新闻中的digest字段

还有pickle对字符串序列化和反序列化

配合使用

我们写个test

import operations
import os
import sys from sets import Set # import common package in parent directory
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common')) # Start Redis and MongoDB before running following tests. def test_getNewsSummariesForUser_basic():
news = operations.getNewsSummariesForUser('test', )
print news
assert len(news) >
print 'test_getNewsSummariesForUser_basic passed!' def test_getNewsSummariesForUser_pagination():
news_page_1 = operations.getNewsSummariesForUser('test', )
news_page_2 = operations.getNewsSummariesForUser('test', ) assert len(news_page_1) >
assert len(news_page_2) > # Assert that there is no dupe news in two pages.
digests_page_1_set = Set([news['digest'] for news in news_page_1])
digests_page_2_set = Set([news['digest'] for news in news_page_2])
assert len(digests_page_1_set.intersection(digests_page_2_set)) == print 'test_getNewsSummariesForUser_pagination passed!' if __name__ == "__main__":
test_getNewsSummariesForUser_basic()
test_getNewsSummariesForUser_pagination()

operations_test.py

下面我们来运行一下

后端api完成让那个了

没回到前端webserver的client的Base

将原来的超链接换成router的link to

同理 loginForm也要修改

signup也是.

然后还要在NewsPannel做一些工作 之前比较简单 只是state保存一些信息 通过loadmorenews获得更多news

现在我们state除了这些 还要记录分页 总页数 加载完没有

然后loadmorenews

然后做个判断

然后 还记得我们的获取新闻的api对象的webserver的server端的news.js是临时数据

news.js吗 我们去修改一下 让他从真正的后端backendserver从数据库拿数据

var express = require('express');
var router = express.Router(); var rpc_client = require('../rpc_client/rpc_client'); /* GET news summary list. */
router.get('/userId/:userId/pageNum/:pageNum', function(req, res, next) {
console.log('Fetching news...');
user_id = req.params['userId'];
page_num = req.params['pageNum']; rpc_client.getNewsSummariesForUser(user_id, page_num, function(response) {
res.json(response);
});
}); /* Log news click. */
router.post('/userId/:userId/newsId/:newsId', function(req,res, next) {
console.log('Logging news click...');
user_id = req.params['userId'];
news_id = req.params['newsId']; rpc_client.logNewsClickForUser(user_id, news_id);
res.status();
}); module.exports = router;

news.js

所以我们回去带上这两个参数

ok

再回到webserver  server去

然后我们的真正的后端backend server

具体实现

等这些操作完成后又回到web server的server去了

我们洗个test验证一下

我们先将后端骑起来

他说找不到这个方法

我们去看看

在运行

返回空 因为没有这个userid

下面前端和后端调通(从网页上看到效果)

首先在web server的client先build一下(将前端页面文件传到build文件中)

然后去server 起一个端口 npm start 就可以只开一个端口来调试了

week07 codelab02 C72的更多相关文章

  1. Week07《Java程序设计》第七次作业总结

    Week07<Java程序设计>第七次作业总结 1. 本周学习总结 1.1 思维导图:Java图形界面总结 答: 1.2 可选:使用常规方法总结其他上课内容. 答: 1. Swing组件: ...

  2. 20162328蔡文琛week07

    学号 2016-2017-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 多态引用在不同的时候可以指向不同类型的对象. 多态引用在运行时才将方法调用用于它的定义绑定在一起. 引 ...

  3. week07 13.3 NewsPipeline之 三News Deduper之 tf_idf 查重

    我们运行看结果 安装包sklearn 安装numpy 安装scipy 终于可以啦 我们把安装的包都写在文件里面吧 4行4列 轴对称 只需要看一半就可以 横着看 竖着看都行 数值越接近1 表示越相似 我 ...

  4. week07 13.4 NewsPipeline之 三 News Deduper

    还是循环将Q2中的东西拿出来 然后查重(去mongodb里面把一天之内的新闻都拿出来,然后把拿到的新的新闻和mongodb里一天内的新闻组一个 tf-idf的对比)可看13.3 相似度检查 如果超过一 ...

  5. week07 13.2 NewsPipeline之 二 News Fetcher - Xpath

    我们使用Xpath来专门做一个scrapter 我们专门弄个文件夹 里面全部是 各个新闻源(CNN BBC等)的scraper来抓取网站的text内容 主要函数(就是传入text内容的那个url)然后 ...

  6. week07 13.1 NewsPipeline之 一 NewsMonitor

    我们要重构一下代码 因为我们之前写了utils 我们的NewsPipeline部分也要用到 所以我们把他们单独独立得拿出来 删掉原来的 将requirements.txt也拿出去 现在我们搬家完成 我 ...

  7. 20162328蔡文琛 大二week07

    20162328 2017-2018-1 <程序设计与数据结构>第7周学习总结 教材学习内容总结 树是非线性结构,其元素组织为一个层次结构. 树的度表示树种任意节点的最大子节点数. 有m个 ...

  8. Python基础-week07 Socket网络编程

    一 客户端/服务器架构 1.定义 又称为C/S架构,S 指的是Server(服务端软件),C指的是Client(客户端软件) 本章的中点就是教大写写一个c/s架构的软件,实现服务端软件和客户端软件基于 ...

  9. shell脚本批量收集linux服务器的硬件信息快速实现

    安装ansible批量管理系统.(没有的话,ssh远程命令循环也可以) 在常用的数据库里面新建一张表,用你要收集的信息作为列名,提供可以用shell插入.

随机推荐

  1. Verilog手绘FVH信号

    Verilog手绘FVH信号 `timescale 1ns / 1ps //////////////////////////////////////////////////////////////// ...

  2. (引用)!Unicode,GBK以及UTF8的联系和区别

    在实现单片机显示汉字的操作时,了解到有关汉字编码的相关概念. Unicode是一种字符集,该字符集可以涵盖世界上所有的语言.最常见的字符集是ASC II-0~127(0x00~0x7f).Unicod ...

  3. Ajax异步请求阻塞情况的解决办法(asp.net MVC Session锁的问题)

    讨论今天这个问题之前,我们先来看下浏览器公布的资源并发数限制个数,如下图 不难看出,目前主流浏览器支持都是最多6个并发 需要注意的是,浏览器的并发请求数目限制是针对同一域名的 意即,同一时间针对同一域 ...

  4. unity最基本操作

    1. 2017.1.0  2017.1.1 2017.2.0 2017.3.4  5.5.3  p4 小版本号高出现bug可能性更小:一台电脑可以安装多个版本的unity,但是需要安装在不同路径:安装 ...

  5. Centos7开机启动自己的脚本的方法

    在百度上可以找到好几种Linux开机启动各种服务的方法,在这里我写的是自己喜欢的方式. 博主是一个不怎么记事的人,有些配置在系统的目录下,配置了一次后就忘了,再也不想去系统的目录下找各种奇奇怪怪的目录 ...

  6. spring入门-注解的使用

    说明: 使用注解和使用配置文件实现的功能是一样的,都是为了解耦,但是配置文件语法属于非编程语言法语,无法调试,难以定位bug,使用注解更易定位问题. 配置步骤 编译器必须先安装了STS插件 第一步 导 ...

  7. 03-在tomcat部署网站多个网站

    在Tomcat服务器发布两个项目 CRM  OA server.xml配置文件 <Context docBase="C:\crm" path="/crm" ...

  8. Java中static、final、static final的区别(转)

    说明:不一定准确,但是最快理解. final: final可以修饰:属性,方法,类,局部变量(方法中的变量) final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变. final ...

  9. hive动态分区问题--分区为中文

    报错如下: Loading data to table data_da.tmp_wlw_test partition (stat_date=2017-05-11, business_type_name ...

  10. 如何实现 C/C++ 与 Python 的通信?

    属于混合编程的问题.较全面的介绍一下,不仅限于题主提出的问题.以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格) 本文分4个部分 1. C/C++ 调用 Python (基础篇 ...