def _operateSetting(argv, usage, actions): try: assert len(argv) == 4 or len(argv) == 5 assert argv[1] in actions if len(argv) == 4: argv.append('') action, email, key, value = argv[1:] user_model = sh.model('User') setting_model = sh.model('Setting') user = user_model.getByEmail(email) if not user: print 'ERROR: user %s is not exists' % email exit(0) exists = setting_model.getOneByWhere('Userid=%s and type=%s', user.id, key) if action == 'get': if exists: print exists.value elif action == 'set': if exists: setting_model.update(exists.id, {'value': value}) else: setting_model.insert({'Userid': user.id, 'type': key, 'value': value}) elif action == 'delete': if exists: setting_model.delete(exists.id) except Exception: print usage
def test_multi_delete(self): # reset tag model decorator = [('Tag', dict(tag_model_name='Tag', data_key='tags', \ split_char=' ', auto_operate='reset'))] model = sh.model('ForTestTag', decorator) tag_model = sh.model('Tag') # 插入一个数据 new_id_1 = model.insert(dict(title='python', tags='script')) new_id_2 = model.insert(dict(title='c++', tags='compiled')) # Tag表保存了相关数据 tag_items = tag_model.all() self.assertEqual(len(tag_items), 2) self.assertEqual(tag_items[0].name, 'script') self.assertEqual(tag_items[1].name, 'compiled') # 删除这个数据, Tag表中的数据也被删除 model.delete(new_id_1) tag_items = tag_model.all() self.assertEqual(len(tag_items), 1) self.assertEqual(tag_items[0].name, 'compiled') # 使用removeTag删除标签,Tag表中的数据也被删除 model.removeTag(new_id_2, 'compiled') self.assertFalse(model.hasTag(new_id_2, 'compiled')) self.assertEqual(tag_model.all(), []) # 每个标签在Tag表中保存一个记录 model.insert(dict(title='shell', tags='power complex cool')) self.assertEqual(len(tag_model.all()), 3)
def __getattr__(self, key): try: if key == 'id': key = self._primary_key return web.Storage.__getattr__(self, key) except AttributeError: key = key.replace('_', '') # 以方便item.abc_def替代item.abcdef if ModelData.model_names.has_key(key): model_name = ModelData.model_names[key] table_name = model_name.rpartition('.')[2] if self.has_key(table_name + 'id'): try: return sh.model(model_name).get( self.get(table_name + 'id')) except: print 'ERROR: ModelData找不到属性', key raise if key.endswith('s') and ModelData.model_names.has_key(key[:-1]): model_name = ModelData.model_names[key[:-1]] table_name = model_name.rpartition('.')[2] id_key = self.get('_table_name') + 'id' if self.db.isColumnExists(table_name, id_key): try: return sh.model(model_name).all( {'where': [id_key + '=%s', self.id]}) except: print 'ERROR: ModelData找不到属性', key raise raise
def sendValidationEmail(self, user): code = self.__getValidationCode(user) sh.model('UserValidation').replaceInsert( dict(Userid=user.id, code=code)) mail_text = '欢迎%s\n请点击激活: %s/accounts/validate?Userid=%d&code=%s' % ( user.name, sh.config.HOST_NAME, user.id, code) sh.sendMail(user.email, '欢迎注册,请验证', mail_text)
def test_POST(self): f_model = sh.model('UserForgetPassword') my_id = self.register() # 设置Userid后便可以删除 new_id = f_model.insert(dict(Userid=my_id, code='c')) self.assertIsNotNone(f_model.get(new_id)) data = {'model_name': 'UserForgetPassword', 'model_id': new_id} self.get(api_url, data) self.assertIsNone(f_model.get(new_id)) # 删除不存在的数据会返回True,但是affected等于0 res = self.get(api_url, data) res = sh.loadsJson(res) self.assertTrue(res.success) self.assertEqual(res.affected, 0) # 如果没有登录的话,是不能删除的 data['model_id'] = f_model.insert(dict(Userid=my_id, code='c')) self.logout() res = self.get(api_url, data) res = sh.loadsJson(res) self.assertFalse(res.success) # 不能删除别人的数据 my_id = self.register() new_id = f_model.insert(dict(Userid=my_id+1, code='c')) data['model_id'] = new_id res = self.get(api_url, data) res = sh.loadsJson(res) self.assertFalse(res.success) # 如果没有Userid属性的话,是不能删除的 s_model = sh.model('SiteConfig') new_id = s_model.insert(dict(name='n', value='v')) res = self.get(api_url, {'model_name': 'SiteConfig', 'model_id': new_id}) res = sh.loadsJson(res) self.assertFalse(res.success) self.assertIsNotNone(s_model.get(new_id))
def sendForgetPasswordEmail(self, user): code = self.__getValidationCode(user) sh.model('UserForgetPassword').replaceInsert( dict(Userid=user.id, code=code)) mail_text = '%s您好,请申请了密码重置,此链接将在24小时后过期\n%s/accounts/forget-password?Userid=%d&code=%s\n若非您本人操作,请忽略本邮件' % ( user.name, sh.config.HOST_NAME, user.id, code) sh.sendMail(user.email, '重置您的密码', mail_text)
def GET(self): inputs = sh.inputs() assert (inputs.has_key('code')) assert (inputs.has_key('state')) site_name = inputs.state.partition('_')[0] authorization_code = inputs.code.strip() oauth_ctrl = sh.ctrl('oauth.%s' % site_name) oauth_model = sh.model('oauth.%sOAuth2' % site_name) user_ctrl = sh.ctrl('User') user_model = sh.model('User') token_url = oauth_ctrl.createAccessTokenUrl(authorization_code) content = sh.requestHtmlContent(token_url, None, oauth_ctrl.ACCESS_TOKEN_METHOD) assert content, u'第三方返回的数据有误' access_token, access_expires = oauth_ctrl.pickAccessTokenAndExpires( content) requested_uid = oauth_ctrl.requestUidWithAccessToken(access_token) assert requested_uid, u'第三方返回的数据有误' if self.TEST_API_LOGIN: login_url = '%s/api/oauth/login?access_token=%s&access_expires=%s&uid=%s&state=%s' % ( sh.config.HOST_NAME, access_token, access_expires, requested_uid, inputs.state) return '<a href="%s" >%s</a>' % (login_url, login_url) # 因为access_token是动态变化的,所以要用requested_uid来判断是否登录过 # 这也避免了access_token变化时插入重复的uid exists = oauth_model.getByUid(requested_uid) # 如果当前uid还没有插入数据库,则先插入再考虑绑定Userid if not exists: new_oauth_id = oauth_model.insert( dict(uid=requested_uid, access_token=access_token, access_expires=access_expires)) exists = oauth_model.get(new_oauth_id) # 如果已绑定Userid则登录 if exists.Userid: return self.login(exists.Userid) # 如果希望自动注册,则注册并绑定后登录 if self.NO_REGISTER_ACTION == 'auto_register': data = oauth_ctrl.assignUserInfo(sh.storage(), access_token) self.assignRandomPassword(data) self.assignRegisterIP(data) conflict = user_ctrl.checkNewUser(data) if conflict: return self.redirectToRegister(access_token, inputs.state, error=conflict) new_user_id = user_model.insert(data) oauth_model.update(exists.id, dict(Userid=new_user_id)) return self.login(new_user_id) # 否则希望用户自己注册 elif self.NO_REGISTER_ACTION == 'to_register': return self.redirectToRegister(access_token, inputs.state)
def __getattr__(self, key): db = DBHelper.DBHelper() try: if key == 'id': key = self._primary_key return web.Storage.__getattr__(self, key) except AttributeError: key = key.replace('_', '') # 以方便item.abc_def替代item.abcdef if ModelData.model_names.has_key(key): model_name = ModelData.model_names[key] table_name = model_name.rpartition('.')[2] if self.has_key(table_name + 'id'): try: return sh.model(model_name).get(self.get(table_name + 'id')) except: print 'ERROR: ModelData找不到属性', key raise if key.endswith('s') and ModelData.model_names.has_key(key[:-1]): model_name = ModelData.model_names[key[:-1]] table_name = model_name.rpartition('.')[2] id_key = self.get('_table_name') + 'id' if db.isColumnExists(table_name, id_key): try: return sh.model(model_name).all({'where': [id_key + '=%s', self.id]}) except: print 'ERROR: ModelData找不到属性', key raise raise
def __getattr__(self, key): try: if key == 'id': key = self._primary_key return web.Storage.__getattr__(self, key) except AttributeError: if ModelData.table_names.has_key(key): table_name = ModelData.table_names[key] if self.has_key(table_name + 'id'): try: return sh.model(table_name).get( self.get(table_name + 'id')) except: print 'ERROR: ModelData找不到属性', key raise if key.endswith('s') and ModelData.table_names.has_key(key[:-1]): table_name = ModelData.table_names[key[:-1]] id_key = self.get('_table_name') + 'id' if self.db.isColumnExists(table_name, id_key): try: return sh.model(table_name).all( {'where': (id_key + '=%s', [self.id])}) except: print 'ERROR: ModelData找不到属性', key raise raise
def POST(self, inputs=None): if not inputs: inputs = sh.inputs() assert inputs.has_key("action") if inputs.action == "postImage": assert inputs.get("Userid", 0) assert sh.model("User").get(inputs.Userid) assert inputs.get("data_name", None) assert inputs.get("data_id", None) img_model = sh.model("UserImage") image_data = sh.getSwfUploadImageFile() new_id = img_model.insert( sh.storage( dict( image_file=image_data, Userid=inputs.Userid, file_name=image_data.filename, data_name=inputs.data_name, data_id=inputs.data_id, ) ) ) return "success;%d;%s;%s" % (new_id, img_model.getUrlByPrivate(inputs.Userid, new_id), image_data.filename)
def GET(self): inputs = sh.inputs() assert inputs.has_key("code") assert inputs.has_key("state") site_name = inputs.state.partition("_")[0] authorization_code = inputs.code.strip() oauth_ctrl = sh.ctrl("oauth.%s" % site_name) oauth_model = sh.model("oauth.%sOAuth2" % site_name) user_ctrl = sh.ctrl("User") user_model = sh.model("User") token_url = oauth_ctrl.createAccessTokenUrl(authorization_code) content = sh.requestHtmlContent(token_url, None, oauth_ctrl.ACCESS_TOKEN_METHOD) assert content, u"第三方返回的数据有误" access_token, access_expires = oauth_ctrl.pickAccessTokenAndExpires(content) requested_uid = oauth_ctrl.requestUidWithAccessToken(access_token) assert requested_uid, u"第三方返回的数据有误" if self.TEST_API_LOGIN: login_url = "%s/api/oauth/login?access_token=%s&access_expires=%s&uid=%s&state=%s" % ( sh.config.HOST_NAME, access_token, access_expires, requested_uid, inputs.state, ) return '<a href="%s" >%s</a>' % (login_url, login_url) # 因为access_token是动态变化的,所以要用requested_uid来判断是否登录过 # 这也避免了access_token变化时插入重复的uid exists = oauth_model.getByUid(requested_uid) # 如果当前uid还没有插入数据库,则先插入再考虑绑定Userid if not exists: new_oauth_id = oauth_model.insert( dict(uid=requested_uid, access_token=access_token, access_expires=access_expires) ) exists = oauth_model.get(new_oauth_id) # 如果已绑定Userid则登录 if exists.Userid: return self.login(exists.Userid) # 如果希望自动注册,则注册并绑定后登录 if self.NO_REGISTER_ACTION == "auto_register": data = oauth_ctrl.assignUserInfo(sh.storage(), access_token) self.assignRandomPassword(data) self.assignRegisterIP(data) conflict = user_ctrl.checkNewUser(data) if conflict: return self.redirectToRegister(access_token, inputs.state, error=conflict) new_user_id = user_model.insert(data) oauth_model.update(exists.id, dict(Userid=new_user_id)) return self.login(new_user_id) # 否则希望用户自己注册 elif self.NO_REGISTER_ACTION == "to_register": return self.redirectToRegister(access_token, inputs.state)
def _delete(self, inputs=None): assert(sh.session.is_admin) if inputs is None: inputs = sh.inputs() assert(inputs.has_key('model_name')) assert(inputs.has_key('model_id')) model = sh.model(inputs.model_name) model.delete(int(inputs.model_id)) return sh.model(inputs.model_name).update(int(inputs.model_id),inputs)
def login(self, user, remember_me=False, ignore_cookie=False, inc_count=True): sh.session.id = user.id sh.session.is_login = True sh.session.name = user.name if remember_me and not ignore_cookie: sh.setCookie('email', user.email) sh.setCookie('md5password', user.password) if user.has_key('login_count') and inc_count: sh.model(self.model_name).update(user.id, {'login_count': user.login_count+1})
def test_sh_model(self): image_model2 = sh.model('Image') self.assertIs(image_model2, image_model) # 指明decorator参数时则不使用单例模式 decorator = [('Orderby', dict(orderby='{$primary_key} desc')),] image_model3 = sh.model('Image', decorator) self.assertIsNot(image_model3, image_model) image_model4 = sh.model('Image', decorator) self.assertIsNot(image_model4, image_model3) # sh.model的decorator参数仅能用于测试环境 sh.config.IS_TEST = False self.assertRaises(AssertionError, sh.model, 'Image', decorator) sh.config.IS_TEST = True
def test_delete_delete(self): decorator = [('Cascade', dict( delete=[('Image', 'data_id'), ], ))] # 插入一个user id1 = sh.model('User').insert(test_user_data) # 插入一张图片, 并关联data_id为Userid image_data = {image_model.image_key: test_image_data, 'data_id': id1} id2 = image_model.insert(image_data) # 删除user user_model = sh.model('User', decorator) user_model.delete(id1) # 图片数据也被删除 self.assertIsNone(image_model.get(id2))
def GET(self): inputs = sh.inputs() assert(inputs.has_key('Userid')) assert(inputs.has_key('code')) model = sh.model('UserValidation') exists = model.getOneByWhere('Userid=%s and code=%s', inputs.Userid, inputs.code) if exists: sh.model('User').update(inputs.Userid, dict(activated='yes')) model.delete(exists.id) return sh.alert('验证邮箱成功') else: return sh.redirectTo404()
def test_delete_delete(self): decorator = [('Cascade', dict(delete=[ ('Image', 'data_id'), ], ))] # 插入一个user id1 = sh.model('User').insert(test_user_data) # 插入一张图片, 并关联data_id为Userid image_data = {image_model.image_key: test_image_data, 'data_id': id1} id2 = image_model.insert(image_data) # 删除user user_model = sh.model('User', decorator) user_model.delete(id1) # 图片数据也被删除 self.assertIsNone(image_model.get(id2))
def test_sh_model(self): image_model2 = sh.model('Image') self.assertIs(image_model2, image_model) # 指明decorator参数时则不使用单例模式 decorator = [ ('Orderby', dict(orderby='{$primary_key} desc')), ] image_model3 = sh.model('Image', decorator) self.assertIsNot(image_model3, image_model) image_model4 = sh.model('Image', decorator) self.assertIsNot(image_model4, image_model3) # sh.model的decorator参数仅能用于测试环境 sh.config.IS_TEST = False self.assertRaises(AssertionError, sh.model, 'Image', decorator) sh.config.IS_TEST = True
def _operateSetting(argv, usage, actions): try: assert len(argv) == 3 or len(argv) == 4 assert argv[1] in actions if len(argv) == 3: argv.append('') action, name, value = argv[1:] model = sh.model('SiteConfig') exists = model.getOneByWhere('name=%s', name) if action == 'get': if exists: print exists.value elif action == 'set': if exists: model.update(exists.id, {'value': value}) else: model.insert({'name': name, 'value': value}) elif action == 'delete': if exists: model.delete(exists.id) except Exception: print usage
def assignUserInfo(self, data, access_token): new_data = sh.copy(data) if data else sh.storage() exists = sh.model(self.MODEL_NAME).getByAccessToken(access_token) if not exists: return new_data res = sh.requestHtmlContent(self.USER_INFO_URL, ( 'access_token', access_token, 'oauth_consumer_key', self.getAppID(), 'openid', exists.uid, 'format', 'json', )) if not res: return new_data res = sh.loadsJson(res) if res.ret != 0: return new_data if not new_data.has_key('name'): new_data['name'] = res.nickname if res.gender == '男': new_data['sex'] = '他' elif res.gender == '女': new_data['sex'] = '她' image_file = sh.requestImageFile(res.figureurl_2) if image_file: new_data['image_file'] = image_file return new_data
def assignUserInfo(self, data, access_token): new_data = sh.copy(data) if data else sh.storage() exists = sh.model(self.MODEL_NAME).getByAccessToken(access_token) if not exists: return new_data res = sh.requestHtmlContent(self.USER_INFO_URL, ( 'access_token', access_token, 'oauth_consumer_key', self.getAppID(), 'uid', exists.uid, )) if not res: return new_data res = sh.loadsJson(res) if res.get('error_code', None): return new_data if not new_data.has_key('name'): new_data['name'] = res.screen_name if res.gender == 'm': new_data['sex'] = '他' elif res.gender == 'f': new_data['sex'] = '她' else: new_data['sex'] = '保密' image_file = sh.requestImageFile(res.avatar_large) if image_file: new_data['image_file'] = image_file return new_data
def GET(self): inputs = sh.inputs() assert inputs.has_key('model_name'), u'请指定需要裁剪的数据类型' assert inputs.has_key('model_id'), u'请指定需要裁剪的数据ID' assert inputs.has_key('crop'), u'请设置裁剪配置' item = sh.model(inputs.model_name).get(inputs.model_id) if not item or not item.has_key('Imageid'): return sh.redirectTo404() column_name, settings = sh.unquote(inputs.crop).partition(' ')[::2] inputs.crop_width, settings = settings.strip().partition(' ')[::2] preview_size, settings = settings.strip().partition(' ')[::2] inputs.preview_width, inputs.preview_height = preview_size.split(':') inputs.column_name = column_name inputs.crop_settings = settings inputs.image = item.image if item.get(column_name): inputs.crop = item.get(column_name) else: inputs.crop = '0 0 %s %s' % tuple(preview_size.split(':')) if len(inputs.crop.split()) == 4: x1, y1, x2, y2 = map(int, inputs.crop.split(' ')) inputs.fx_crop = 'x1=%s;y1=%s;x2=%s;y2=%s;' % (x1,y1,x1+x2,y1+y2) else: inputs.fx_crop = '' return sh.editor.CropImage(inputs)
def test_multi(self): model = sh.model("ForTestCategory") # 插入ForTestCategory new_id = model.insert(dict(title="python", cat="computer")) item = model.get(new_id) # 自动插入了Categoryid self.assertIsNotNone(item.category) self.assertEqual(item.category.name, "computer") self.assertEqual(model.getCategory(new_id), "computer") # 设置不存在的分类时抛出异常 self.assertRaises(AssertionError, model.setCategory, new_id, "psychics") # 但可以通过addCategory添加一个新分类 model.addCategory("psychics") self.assertEqual(model.getCategory(new_id), "computer") # 然后用setCategory设置 model.setCategory(new_id, "psychics") self.assertEqual(model.getCategory(new_id), "psychics") # 用getAllCategory获得已有的两个分类 self.assertEqual(model.getAllCategory(), ["computer", "psychics"]) # 可用hasCategory判断是否已有某分类 self.assertTrue(model.hasCategory("computer")) self.assertTrue(model.hasCategory("psychics")) self.assertFalse(model.hasCategory("math")) # addNewCategory也可以添加分类,但是不能已存在 model.addNewCategory("math") self.assertTrue(model.hasCategory("math")) self.assertRaises(AssertionError, model.addNewCategory, "math") # 通过update可以自动设置新分类 model.update(new_id, dict(cat="language")) self.assertEqual(model.getCategory(new_id), "language") self.assertEqual(model.get(new_id).category.name, "language")
def setUp(self): model = sh.model('SiteConfig') # 使用truncate是为了每个test中SiteConfigid从1开始 db.executeQuery('truncate %s' % model.table_name) model.insert({'name': 'n1', 'value': 'v1', 'title': 't1'}) model.insert({'name': 'n2', 'value': 'v2', 'title': 't2'}) model.insert({'name': 'n3', 'value': 'v3', 'title': 't3'})
def POST(self): inputs = sh.inputs() if inputs['action'] == 'isLogin': if sh.session.is_login: return sh.toJsonp({'is_login': True, 'name': sh.session.name, 'id': sh.session.id}) else: return sh.toJsonp({'is_login': False, 'name': '', 'id': 0}) if inputs['action'] == 'login': assert(inputs.get('email', '').strip()) assert(inputs.get('password', '')) model = sh.model('User') uc = sh.ctrl('User') if not uc.validate(inputs.email, inputs.password): return sh.toJsonp({'is_login':False, 'error':'邮箱或密码不对'}) user = model.getByEmail(inputs.email) if user.dead == 'yes': return sh.toJsonp({'is_login':False, 'error':'你已被列入黑名单'}) uc.login(user, inputs.get('remember_me', '') == 'on') return sh.toJsonp({'is_login':True, 'name': user.name, 'id': user.id}) if inputs['action'] == 'logout': sh.ctrl('User').logout() return 'bye'
def test_insert_convert(self): image_modle = sh.model('Image') image_model.use_convert = True # 改变图片 image_model.convert_type = 'png' image_model.max_width = 50 image_model.max_height = 60 data = sh.storage({'data_name': 'User', 'data_id': 1, image_model.image_key: test_image_data}) id = image_model.insert(data) item = image_model.get(id) image_path = sh.urlToPath(item.url) # 转换为png格式 self.assertTrue(image_path.endswith('/%d.png' % (id))) self.assertEqual(imghdr.what(None, open(image_path).read()), 'png') # 压缩为50x50. 因为会保持原有比例,所以压缩后高度依然是50, 不是60 self.assertEqual(Image.open(image_path).size, (50, 50)) # 当max_height与max_width有其中之一为None时就不压缩 image_model.max_height = None id2 = image_model.insert(data) item2 = image_model.get(id2) # 虽然不压缩尺寸,但是要转换格式 image_path = sh.urlToPath(item2.url) self.assertTrue(image_path.endswith('/%d.png' % (id2))) # 依然是原来的尺寸 self.assertEqual(Image.open(image_path).size, Image.open(test_image_data.filename).size)
def GET(self): inputs = sh.inputs() assert inputs.has_key('model_name'), u'请指定需要裁剪的数据类型' assert inputs.has_key('model_id'), u'请指定需要裁剪的数据ID' assert inputs.has_key('crop'), u'请设置裁剪配置' item = sh.model(inputs.model_name).get(inputs.model_id) if not item or not item.has_key('Imageid'): return sh.redirectTo404() column_name, settings = sh.unquote(inputs.crop).partition(' ')[::2] inputs.crop_width, settings = settings.strip().partition(' ')[::2] preview_size, settings = settings.strip().partition(' ')[::2] inputs.preview_width, inputs.preview_height = preview_size.split(':') inputs.column_name = column_name inputs.crop_settings = settings inputs.image = item.image if item.get(column_name): inputs.crop = item.get(column_name) else: inputs.crop = '0 0 %s %s' % tuple(preview_size.split(':')) if len(inputs.crop.split()) == 4: x1, y1, x2, y2 = map(int, inputs.crop.split(' ')) inputs.fx_crop = 'x1=%s;y1=%s;x2=%s;y2=%s;' % (x1, y1, x1 + x2, y1 + y2) else: inputs.fx_crop = '' return sh.editor.CropImage(inputs)
def test_multi2(self): model = sh.model('ForTestCategory') new_id_1 = model.insert(dict(title='python', cat='computer')) item_1 = model.get(new_id_1) new_id_2 = model.insert(dict(title='pascal', cat='computer')) # 使用removeCategory删除python的分类 model.removeCategory(new_id_1) self.assertEqual(model.getCategory(new_id_1), None) self.assertIsNotNone(item_1.category) item_1 = model.get(new_id_1) self.assertIsNone(item_1.category) # 但是分类依然存在 self.assertTrue(model.hasCategory('computer')) # item2的分类不受影响 self.assertEqual(model.getCategory(new_id_2), 'computer') # 使用deleteCategory删除所有computer的分类 model.deleteCategory('computer') self.assertFalse(model.hasCategory('computer')) # item2的分类也没了 item_2 = model.get(new_id_2) self.assertEqual(item_2.Categoryid , 0) self.assertEqual(model.getCategory(new_id_2), None) # 给item2设置新分类,并删除item2数据 model.update(new_id_2, dict(cat='old')) model.delete(new_id_2) # item2的分类依然存在 self.assertTrue(model.hasCategory('old'))
def test_multi(self): model = sh.model('ForTestCategory') # 插入ForTestCategory new_id = model.insert(dict(title='python', cat='computer')) item = model.get(new_id) # 自动插入了Categoryid self.assertIsNotNone(item.category) self.assertEqual(item.category.name, 'computer') self.assertEqual(model.getCategory(new_id), 'computer') # 设置不存在的分类时抛出异常 self.assertRaises(AssertionError, model.setCategory, new_id, 'psychics') # 但可以通过addCategory添加一个新分类 model.addCategory('psychics') self.assertEqual(model.getCategory(new_id), 'computer') # 然后用setCategory设置 model.setCategory(new_id, 'psychics') self.assertEqual(model.getCategory(new_id), 'psychics') # 用getAllCategory获得已有的两个分类 self.assertEqual(model.getAllCategory(), ['computer', 'psychics']) # 可用hasCategory判断是否已有某分类 self.assertTrue(model.hasCategory('computer')) self.assertTrue(model.hasCategory('psychics')) self.assertFalse(model.hasCategory('math')) # addNewCategory也可以添加分类,但是不能已存在 model.addNewCategory('math') self.assertTrue(model.hasCategory('math')) self.assertRaises(AssertionError, model.addNewCategory, 'math') # 通过update可以自动设置新分类 model.update(new_id, dict(cat='language')) self.assertEqual(model.getCategory(new_id), 'language') self.assertEqual(model.get(new_id).category.name, 'language')
def test_multi_reset(self): # 给model添加reset tag功能 decorator = [('Tag', dict(tag_model_name='Tag', data_key='tags', \ split_char=' ', auto_operate='reset'))] model = sh.model('ForTestTag', decorator) # 插入一个带有标签的数据 new_id = model.insert(dict(title='python', tags='lang computer simple')) # get得到的数据带有tags标签(无序) self.assertEqual(set(model.get(new_id).tags), set(['lang', 'computer', 'simple'])) # 使用all得到的数据也有tags属性 self.assertEqual(set(model.all()[0].tags), set(['lang', 'computer', 'simple'])) # 更新tags model.update(new_id, dict(tags='fast \t power easy')) # 原有标签被替换 self.assertEqual(set(model.get(new_id).tags), set(['fast', 'power', 'easy'])) # 更新时不指定tags, 标签被保留 model.update(new_id, dict(title='new title')) self.assertEqual(set(model.get(new_id).tags), set(['fast', 'power', 'easy'])) # 使用空字符串更新tags, 标签被清空 model.update(new_id, dict(tags='')) self.assertEqual(model.get(new_id).tags, [])
def POST(self, inputs=None): if not inputs: inputs = sh.inputs() assert(inputs.get('email', '').strip()) assert(inputs.get('password', '')) uc = sh.ctrl('User') model = sh.model('User') action = sh.getEnv('REQUEST_URI').partition('?')[0].strip('/') if action == 'login': if not uc.validate(inputs.email, inputs.password): return sh.page.user.Login('您输入的用户名或密码不对, 请重新输入', inputs.email) user = model.getByEmail(inputs.email) if user.dead == 'yes': return sh.alert('登录失败,你已被列入黑名单,请联系管理员') uc.login(user, inputs.get('remember_me', '') == 'on') # 获得打开login页面时url中指定的referer referer = sh.getUrlParams(sh.getEnv('HTTP_REFERER')).get('referer', None) if referer: return sh.redirect(referer) elif sh.inputs().get('referer', None): return sh.redirect(sh.inputs().get('referer', None)) else: return sh.redirect('/')
def savePortrait(self, Userid, image_file): user_model = sh.model('User') user = user_model.get(Userid) if user.image and image_file: path = sh.urlToPath(user.image.url) os.system('rm %s' % (path + '.crop')) user_model.update(Userid, {sh.model('Image').image_key: image_file}) # 自动设置裁剪区域为整个图片 user = user_model.get(Userid) # 为了重新拿到image数据 size = sh.imageSize(user.image.url) user_model.update(user.id, {'crop': '0 0 %d %d' % size}) path = sh.urlToPath(user.image.url) os.system('cp %s %s' % (path, path + '.crop'))
def POST(self, inputs=None): if not inputs: inputs = sh.inputs() assert(inputs.get('email', '').strip()) assert(inputs.get('password', '')) uc = sh.ctrl('User') model = sh.model('User') action = sh.getEnv('REQUEST_URI').partition('?')[0].strip('/') if action == 'login': if not uc.validate(inputs.email, inputs.password): return sh.page.user.Login('您输入的用户名或密码不对, 请重新输入', inputs.email) user = model.getByEmail(inputs.email) if user.dead == 'yes': return sh.alert('登录失败,你已被列入黑名单,请联系管理员') uc.login(user, inputs.get('remember_me', '') == 'on') # 获得打开login页面时url中指定的referer referer = sh.getUrlParams(sh.getEnv('HTTP_REFERER')).get('referer', None) if referer: return sh.redirect(referer) elif sh.inputs().get('referer', None): return sh.redirect(sh.inputs().get('referer', None)) else: return sh.alert('登录成功. 欢迎回来!')
def test_multi2(self): model = sh.model("ForTestCategory") new_id_1 = model.insert(dict(title="python", cat="computer")) item_1 = model.get(new_id_1) new_id_2 = model.insert(dict(title="pascal", cat="computer")) # 使用removeCategory删除python的分类 model.removeCategory(new_id_1) self.assertEqual(model.getCategory(new_id_1), None) self.assertIsNotNone(item_1.category) item_1 = model.get(new_id_1) self.assertIsNone(item_1.category) # 但是分类依然存在 self.assertTrue(model.hasCategory("computer")) # item2的分类不受影响 self.assertEqual(model.getCategory(new_id_2), "computer") # 使用deleteCategory删除所有computer的分类 model.deleteCategory("computer") self.assertFalse(model.hasCategory("computer")) # item2的分类也没了 item_2 = model.get(new_id_2) self.assertEqual(item_2.Categoryid, 0) self.assertEqual(model.getCategory(new_id_2), None) # 给item2设置新分类,并删除item2数据 model.update(new_id_2, dict(cat="old")) model.delete(new_id_2) # item2的分类依然存在 self.assertTrue(model.hasCategory("old"))
def test_update(self): image_modle = sh.model('Image') image_model.use_convert = False # 不改变图片 data = sh.storage({ 'data_name': 'User', 'data_id': 1, image_model.image_key: test_image_data }) id = image_model.insert(data) item = image_model.get(id) # 更新图片数据 image_model.update( id, { 'image_file': { 'filename': 'new', 'value': 'new', 'imagetype': 'png' }, 'data_id': 2 }) item2 = image_model.get(id) # 其它数据更新成功 self.assertEqual(item2.data_id, 2) # url不变 self.assertEqual(item.url, item2.url) # 图片数据不变 image_path = image_modle.getFilePath(id) self.assertEqual(open(image_path).read(), test_image_data.value)
def POST(self): inputs = sh.inputs() assert inputs.has_key('model_name'), u'请指定需要裁剪的数据类型' assert inputs.has_key('model_id'), u'请指定需要裁剪的数据ID' assert inputs.has_key('column_name'), u'请指定裁剪的列名' assert int(float(inputs.get('region_width', '0'))) > 0 assert int(float(inputs.get('region_height', '0'))) > 0 model = sh.model(inputs.model_name) item = model.get(inputs.model_id) image = item.image real_width, real_height = sh.imageSize(image.url) # 图片的真实宽高 crop = inputs.crop region_width = int(float(inputs.region_width)) # 选择区域的宽度 region_height = int(float(inputs.region_height)) # 选择区域的高度 start_x = int(crop.split()[0]) # 选中的起始位置 start_y = int(crop.split()[1]) region_x = int(crop.split()[2])# 选中的宽度 region_y = int(crop.split()[3]) # 选中的高度 # convert 裁剪区域 region = '%dx%d+%d+%d' % (region_x * real_width / region_width, region_y * real_height / region_height, real_width * start_x / region_width, real_height * start_y / region_height) path = sh.urlToPath(image.url) os.system('convert %s -crop %s %s' % (path, region, path+'.crop')) model.update(inputs.model_id, {inputs.column_name: crop}) return sh.refresh()
def _operateSetting(argv, usage, actions): try: assert len(argv) == 3 or len(argv) == 4 assert argv[1] in actions if len(argv) == 3: argv.append('') action, name, value = argv[1:] model = sh.model('SiteConfig') exists = model.getOneByWhere('name=%s', [name]) if action == 'get': if exists: print exists.value elif action == 'set': if exists: model.update(exists.id, {'value': value}) else: model.insert({'name': name, 'value': value}) elif action == 'delete': if exists: model.delete(exists.id) except Exception: print usage
def test_POST(self): model = sh.model('UserForgetPassword') my_id = self.register() res = self.get(api_url, { 'model_name': 'UserForgetPassword', 'code': 'c' }) res = sh.loadsJson(res) # 成功插入数据 item = model.get(res.new_id) self.assertIsNotNone(item) self.assertEqual(item.code, 'c') # 自动写入Userid self.assertEqual(item.Userid, my_id) # 不能自定义Userid res = self.get(api_url, { 'model_name': 'UserForgetPassword', 'code': 'c', 'Userid': 1 }) res = sh.loadsJson(res) self.assertFalse(res.success) # 不登录的话是不能插入数据的 old_count = model.getCount() self.logout() res = self.get(api_url, { 'model_name': 'UserForgetPassword', 'code': 'c' }) res = sh.loadsJson(res) self.assertEqual(old_count, model.getCount()) self.assertFalse(res.success) self.assertFalse(res.has_key('new_id'))
def savePortrait(self, Userid, image_file): user_model = sh.model('User') user = user_model.get(Userid) if user.image and image_file: path = sh.urlToPath(user.image.url) os.system('rm %s' % (path+'.crop')) user_model.update(Userid, {sh.model('Image').image_key: image_file}) # 自动设置裁剪区域为整个图片 user = user_model.get(Userid) # 为了重新拿到image数据 size = sh.imageSize(user.image.url) user_model.update(user.id, {'crop': '0 0 %d %d' % size}) path = sh.urlToPath(user.image.url) os.system('cp %s %s' % (path, path+'.crop'))
def checkNewUser(self, data): email = data.get('email', '').strip() name = data.get('name', '').strip() password = data.get('password', '') model = sh.model(self.model_name) if not re.match(r"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$", email): return '请输入正确的邮箱地址' if model.getByEmail(email): return '此邮箱已注册' if model.getByName(name): return '此用户名已注册' if not (4 <= len(name) <= 30): return '用户名必须大于等于4个字符,小于等于30个字符' if not (6 <= len(password) < 60): return '密码必须大于等于6个字符,小于等于60个字符' # 限制用户名字符 #if not re.match(r'^[a-zA-Z0-9_]+$', data.name.encode('utf-8')): # return '用户名只能使用字母、数字、下划线' return None
def checkNewUser(self, data): email = data.get('email', '').strip() name = data.get('name', '').strip() password = data.get('password', '') model = sh.model(self.model_name) if not re.match(r"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$", email): return '请输入正确的邮箱地址' if model.getByEmail(email): return '此邮箱已注册' if model.getByName(name): return '此用户名已注册' if not (4 <= len(name) <=30): return '用户名必须大于等于4个字符,小于等于30个字符' if not(6 <= len(password) <= 60): return '密码必须大于等于6个字符,小于等于60个字符' # 限制用户名字符 #if not re.match(r'^[a-zA-Z0-9_]+$', data.name.encode('utf-8')): # return '用户名只能使用字母、数字、下划线' return None
def POST(self): inputs = sh.inputs() assert inputs.get('access_token', '') assert inputs.get('access_expires', '') assert inputs.get('uid', '') assert inputs.get('state', '') site_name = inputs.state.partition('_')[0] oauth_ctrl = sh.ctrl('oauth.%s' % site_name) oauth_model = sh.model('oauth.%sOAuth2' % site_name) user_ctrl = sh.ctrl('User') user_model = sh.model('User') requested_uid = oauth_ctrl.requestUidWithAccessToken( inputs.access_token) # 如果access_token和uid验证不对,则不让登录 if not requested_uid or requested_uid != inputs.uid: return sh.toJsonp(dict(error="该第三方帐号未绑定任何站内帐号", is_login=False)) exists = oauth_model.getByUid(requested_uid) # 如果当前uid还没有插入数据库,则先插入再考虑绑定Userid if not exists: new_id = oauth_model.insert( dict(uid=requested_uid, access_token=inputs.access_token, access_expires=inputs.access_expires)) exists = oauth_model.get(new_id) if exists.Userid: # 如果已绑定本站帐号 return self.login(exists.Userid) inputs = oauth_ctrl.assignUserInfo(inputs, inputs.access_token) self.assignRandomPassword(inputs) self.assignRegisterIP(inputs) conflict = user_ctrl.checkNewUser(inputs) if conflict: return sh.toJsonp( dict(is_login=False, error=conflict, name=inputs.get('name', ''), sex=inputs.get('sex', ''))) new_id = user_model.insert(inputs) oauth_model.update(exists.id, dict(Userid=new_id)) return self.login(new_id)
def toModel(self, list_or_dict, default_model=None): if default_model: assert isinstance(default_model, str) default_model = sh.model(default_model) def _toModel(ld): if isinstance(ld, str): ld = ld.strip() if ld.isdigit() and default_model: return default_model.get(ld) else: return ld elif isinstance(ld, (dict, sh.storage_class)) \ and ld.has_key('model') and ld.has_key('id') and ld.id.isdigit(): item = sh.model(ld.model).get(ld.id) del ld['model'], ld['id'] if item: item.update(ld) return item elif isinstance(ld, (list, tuple)) and len(ld) == 2 \ and isinstance(ld[0], str) \ and ld[0].isdigit() and default_model \ and isinstance(ld[1], (dict, sh.storage_class)): item = default_model.get(ld[0]) if item: item.update(ld[1]) return item elif isinstance(ld, list): items = map(_toModel, ld) return items if len(items) > 1 else items[0] elif hasattr(ld, 'items'): ret_dict = sh.storage() for k, v in ld.items(): k = k.strip() if k.isdigit() and hasattr(v, 'items') \ and (default_model or (v.has_key('model') and v.has_key('id')) ): if v.has_key('model') and v.has_key('id'): item = sh.model(v.model).get(v.id) del v['model'], v['id'] else: item = default_model.get(k) if item: item.update(v) ret_dict[k] = item elif k.isdigit() and v == '' and default_model: ret_dict[k] = default_model.get(k) else: ret_dict[k] = _toModel(v) return ret_dict else: raise u'未知的情况' if isinstance(list_or_dict, (tuple,list)) and not list_or_dict: return [] res = _toModel(list_or_dict) if isinstance(list_or_dict, list) and not isinstance(res, list): res = [res] return res
def convertImage(self, data, img_id): img_model = sh.model('Image') file_path = img_model.getFilePath(img_id) convert_path = img_model.convertImage(file_path, self.convert_type, max_width=self.max_width, max_height=self.max_height, convert_quality=self.convert_quality, remove_info=self.remove_info, convert_gif=self.convert_gif) if file_path != convert_path: os.system('rm "%s"' % file_path) img_model._updateUrl(data, img_id, convert_path.rpartition('.')[2]) return convert_path
def test_auto_set(self): model = sh.model('ForTestCategory') # 插入ForTestCategory2 new_id = model.insert(dict(title='c++', cat='computer')) self.assertEqual(model.get(new_id).cat, 'computer') self.assertEqual(model.getOneByWhere('title=%s', 'c++').cat, 'computer') self.assertEqual(model.all()[0].cat, 'computer') self.assertEqual(model.gets([new_id])[0].cat, 'computer')
def POST(self,inputs=None): if inputs is None: inputs = sh.inputs() assert(inputs.has_key('model_name')) assert(inputs.has_key('model_id')) assert(sh.session.is_admin) model = sh.model(inputs.model_name) model.delete(int(inputs.model_id)) return sh.refresh()
def test_getUrl_getFilePath(self): image_modle = sh.model('Image') image_model.use_convert = False data = sh.storage({'data_name': 'User', 'data_id': 1, image_model.image_key: test_image_data}) id = image_model.insert(data) item = image_model.get(id) self.assertEqual(item.url, image_model.getUrl(id)) self.assertEqual(sh.urlToPath(item.url), image_model.getFilePath(id))
def POST(self): inputs = sh.inputs() assert inputs.get('access_token', '') assert inputs.get('state', '') assert inputs.get(self.PRIMARY_KEY, '') assert inputs.get('password', '') site_name = inputs.state.partition('_')[0] user_model = sh.model('User') user_ctrl = sh.ctrl('User') oauth_model = sh.model('oauth.%sOAuth2' % site_name) oauth_ctrl = sh.ctrl('oauth.%s' % site_name) cn_site_name = self._getCNSiteName() if self.PRIMARY_KEY == 'email': exists_user = user_model.getByEmail(inputs.email) elif self.PRIMARY_KEY == 'name': exists_user = user_model.getByName(inputs.name) # 如果primary_value没有注册过, 那么新建用户并绑定第三方帐号 if not exists_user: inputs = oauth_ctrl.assignUserInfo(inputs, inputs.access_token) self.assignRegisterIP(inputs) conflict = user_ctrl.checkNewUser(inputs) if conflict: return self._render(conflict) new_id = user_model.insert(inputs) oauth_model.bindUseridByAccessToken(inputs.access_token, new_id) return self.login(new_id) # 否则已经注册过,检查密码是否正确 else: if self.PRIMARY_KEY == 'email': check_password = user_ctrl.validate(inputs.email, inputs.password) elif self.PRIMARY_KEY == 'name': check_password = user_ctrl.validateByName( inputs.name, inputs.password) if not check_password: error = '您已经注册过, 但您输入的密码不正确, 请重新输入' return self._render(error) oauth_model.bindUseridByAccessToken(inputs.access_token, exists_user.Userid) return self.login(exists_user.Userid)
def POST(self, inputs=None): if inputs is None: inputs = sh.inputs() assert (inputs.has_key('model_name')) assert (inputs.has_key('model_id')) assert (sh.session.is_admin) model = sh.model(inputs.model_name) model.delete(int(inputs.model_id)) return sh.refresh()