Forums

unable to detect undefined names ?

from utils import *
**utils.py:**

    #coding:utf8
import datetime
import hashlib
import os
#import urllib
import urllib2
import json

#from django.core.cache import cache
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


def generate_code(plainText):
    return hashlib.sha1(plainText).hexdigest()

def getnowString():
    return datetime.datetime.now().strftime('%Y%m%d%H%M%s%f')

def generate_file_code():
    nowString = getnowString()
    key = "yimi_upload_file_%s" % nowString
    return generate_code(key)

def upload_file_handler(instance,filename):
    date_str = datetime.datetime.now().strftime("%Y%m%d")
    path = date_str +"/"+instance.__class__.__name__.lower()
    suffix = filename.split(".")[-1] or "jpg"
    filename = generate_file_code()+"."+suffix
    return os.path.join(path, filename)

def method_get_api(url):
    response = urllib2.urlopen(url).read()
    dict_data = json.loads(response)
    return dict_data

def method_post_api(url, post_data):
    if post_data:
        json_data = json.dumps(post_data, ensure_ascii=False).encode('utf8')
    else:
        return ''
  #  json_data = json.dumps(post_data)
    print 'json_data==', json_data
    req = urllib2.Request(url, json_data)
    req.add_header('Context-Type', 'application/json;charset=utf-8')
    return_json = urllib2.urlopen(req).read()
    return json.loads(return_json)

def get_user_openid(appid, secret, code):
    url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code' % (appid, secret, code)
    data = method_get_api(url)
    openid = data.get("openid")
    return openid
def convert_get_data(GET, key_list):
    '''翻页时用来继承get提交参数'''
    get_data = ''
    for keyw in key_list:
        if GET.get(keyw):
            get_data += '%s=%s&'%(keyw, GET.get(keyw))
    return get_data

def get_entry_page(entry, count_per_page, page_number):
    '''分页返回page_number页的数据'''
    paginator = Paginator(entry, count_per_page)
    try:
        page_entry = paginator.page(page_number)
    except PageNotAnInteger:
        page_entry = paginator.page(1)
    except EmptyPage:
        page_entry = paginator.page(paginator.num_pages)
    return page_entry

def page_turning(list_obj, request, count=10):
    '''翻页函数'''
    page = int(request.GET.get("p",1))
    matchs = get_entry_page(list_obj, count, page)
    show_pages = range(max(page-4,1),min(page+4,matchs.paginator.num_pages)+1)
    return (matchs, show_pages)


#successed(data):
#    if data.get('errcode') == 0 and data.get('errmsg') == 'ok':
#        return True
#    else:
#        return False
#
#def get_token():
#    token = cache.get(TOKEN_CACHE_KEY)
#    if token:
#        return token
#    else:
#        url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s' % (APPID, APP_SECRET)
#        dict_data = method_get_api(url)
#        token = dict_data.get('access_token')
#        expires_in = dict_data.get('expires_in')
#        if token and expires_in:
#            cache.set(TOKEN_CACHE_KEY, token, expires_in-60)
#        return token
#
#def operate_group(keyword, post_data=None):
#    token = get_token()
#    url = GROUP_API.get(keyword)+token
#    if not token:
#        return
#    if keyword == 'get_all_group':
#        return method_get_api(url)
#    else:
#        return method_post_api(url, post_data)
#
#def get_all_user(next_id=None):
#    '''得到所有用户列表'''
#    suffix = ''
#    if next_id:
#        suffix = '&next_openid=' + next_id
#    return method_get_api('https://api.weixin.qq.com/cgi-bin/user/get?access_token='+get_token()+suffix)
#
#def get_user_info(openid):
#    '''得到用户的详细信息'''
#    url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN' % (get_token(), openid)
#    return method_get_api(url)
#
#
#def create_menu(post_data):
#    '''创建菜单,成功返回True'''
#    url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='+get_token()
#    return_data = method_post_api(url, post_data)
#    return successed(return_data)
#
#def select_menu():
#    '''查询menu'''
#    url = 'https://api.weixin.qq.com/cgi-bin/menu/get?access_token=' + get_token()
#    return method_get_api(url)
#
#def delete_menu():
#    '''删除menu'''
#    url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token='+get_token()
#    return successed(method_get_api(url))

view.py:

#!/usr/bin/env python2.7
#coding:utf8
import re
import hashlib

from django.shortcuts import render_to_response
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse, Http404

from models import AppUser, AppItem

from yimi.settings import TOKEN

from utils import *

REPLY_DATA = '''
    <xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[%s]]></MsgType>
    %s
    </xml>
'''

TYPE_CONTENT_DICT = {
    'text': '<Content><![CDATA[%s]]></Content>',
    'news': '<ArticleCount>%s</ArticleCount><Articles>%s</Articles>'
}

ARTICLES = '''
    <item>
    <Title><![CDATA[%s]]></Title>
    <Description><![CDATA[%s]]></Description>
    <PicUrl><![CDATA[%s]]></PicUrl>
    <Url><![CDATA[%s]]></Url>
    </item>
'''

def gen_xml(instance, app_item):
    retype = instance.message.retype
    type_content = TYPE_CONTENT_DICT.get(retype, '')
    resource = instance.message.get_resource()
   # user_info_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+app_item.appid+'&redirect_uri=%s&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'
    #文本回复
    if retype == 'text':
        content = type_content % resource.content


    #    content = type_content % c

    #图文回复
    elif retype == 'news':
        if not resource:
            return ''
        articles_str = ''
        for article in resource.articles.all():
            art_param = (
                article.title,
                article.description,
                article.get_image_url(),
                article.get_url(),
            )
            articles_str += ARTICLES % art_param
        content = type_content % (resource.articles.count(), articles_str)

    params = (
        instance.from_user,
        instance.to_user,
        instance.message.get_create_time(),
        retype,
        content,
    )
    return REPLY_DATA % params


def home(request):
    return render_to_response('home.html')

def index(request):
    '''网页授权获取用户基本信息'''
    api = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code'%(APPID, APP_SECRET, request.GET.get('code'))
    data = method_get_api(api)
    token = data.get('access_token')
    openid = data.get('openid')

    api2 = 'https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN'%(token, openid)
    print method_get_api(api2)

    return HttpResponse(json_data, content_type="application/json")


class ParseMessage():
    touser_re = r'<ToUserName><!\[CDATA\[(.+)\]\]></ToUserName>'
    fromuser_re = r'<FromUserName><!\[CDATA\[(.+)\]\]></FromUserName>'
    content_re = r'<Content><!\[CDATA\[(.+)\]\]></Content>'
    msgtype_re = r'<MsgType><!\[CDATA\[(.+)\]\]></MsgType>'
    picurl_re = r'<PicUrl><!\[CDATA\[(.+)\]\]></PicUrl>'
    mediaid_re = r'<MediaId><!\[CDATA\[(.+)\]\]></MediaId>'
    msgid_re = r'<MsgId>(\d+)</MsgId>'
    event_re = r'<Event><!\[CDATA\[(.+)\]\]></Event>'
    eventkey_re = r'<EventKey><!\[CDATA\[(.+)\]\]></EventKey>'
    latitude_re = r'<Latitude>(.+)</Latitude>'
    longitude_re = r'<Longitude>(.+)</Longitude>'
    precision = r'<Precision>(.+)</Precision>'

    def __init__(self, body, appitem):
        self.body = body
        self.appitem = appitem

    def parse_xml(self):
        self.to_user = self.re_find(self.touser_re)
        self.from_user = self.re_find(self.fromuser_re)

        self.msgtype = self.re_find(self.msgtype_re)

        if self.msgtype != 'event':
            #关键字回复
            self.content = self.re_find(self.content_re)
            self.message = self.appitem.messages.filter(keyword=self.content, tag='keyword_recontent').first()
            if not self.message:
                #无匹配回复
                self.message = self.appitem.messages.filter(tag='keyword_default_recontent').first()
        else:
            self.event = self.re_find(self.event_re)

            if self.event == 'CLICK':
                #menu click事件
                self.eventkey = self.re_find(self.eventkey_re)
                self.message = self.appitem.messages.filter(tag='keyword_recontent', keyword=self.eventkey).first()
            elif self.event == 'subscribe':
                #关注,是否有EventKey,有的话,就是扫描带参数二维码事件
                self.message = self.appitem.messages.filter(tag=self.event).first()
            elif self.event == 'unsubscribe':
                #取消关注
                pass
            elif self.event == 'LOCATION':
                #地理位置
                pass
            elif self.event == 'SCAN':
                # 扫描带参数二维码事件,用户已关注时的事件推送
                pass


    def re_find(self, re_str):
        data_result = re.findall(re_str, self.body)
        return data_result and data_result[0] or ''


def check(params):
    signature = params.get('signature', '')
    timestamp = params.get('timestamp', '')
    nonce = params.get('nonce', '')
    token = TOKEN

    tmp_str = ''.join(sorted([token, timestamp, nonce]))
    tmp_str = hashlib.sha1(tmp_str).hexdigest()
    if tmp_str == signature:
        return True
    else:
        return False


@csrf_exempt
def weixin_api(request, slug):
    app_item = AppItem.objects.filter(id=slug).first()

    if not app_item or not check(request.GET):
        raise Http404

    #第一次验证开发者,如果失败,手动改is_valid为False,重新验证
    if not app_item.is_valid:
        echostr = request.GET.get('echostr', '')
        app_item.is_valid = True
        app_item.save()
        return HttpResponse(echostr)
    try:
        msg = ParseMessage(request.body, app_item)
        #file('/var/www/body.xml', 'w').write(request.body) #测试
        msg.parse_xml()
        return_data = ''
        if hasattr(msg, 'message'):
            if msg.message:
                return_data = gen_xml(msg, app_item)
    except Exception, data:
        print '22222222222'
        print Exception, ":", data
    try:
        print 'aaaaaaaaaaa'
        if hasattr(msg, 'event'):
            print 'bbbbbbbbbb'
            print msg.event
            #关注后增加用户信息
            if msg.event == 'subscribe':
                openid = msg.from_user
                user_info = app_item.get_user_info(openid)
                user = AppUser.objects.filter(openid=msg.from_user).first()
                if not user:
                    user = AppUser()
                user.nickname = user_info.get('nickname')
                user.openid = user_info.get('openid')
                user.sex = user_info.get('sex')
                user.language = user_info.get('language')
                user.city = user_info.get('city')
                user.province = user_info.get('province')
                user.country = user_info.get('country')
                user.headimgurl = user_info.get('headimgurl')
                user.save()
                if not app_item.app_users.filter(openid=openid).exists():
                    app_item.app_users.add(user)
            elif msg.event == 'unsubscribe':
                openid = msg.from_user
                user = AppUser.objects.filter(openid=openid).first()
                app_item.app_users.remove(user)
    except Exception,data:
        print Exception,":",data

    return HttpResponse(return_data, content_type="application/xhtml+xml")

def message(request):
    return HttpResponse('ok')

[edited by admin: formatting]

I can't really work out what's going on in all that unformatted, unindented text. I'm also not clear on what your question is. Could you narrow it down and reduce the amount of code?

how to format?

先选择你的code 然后按一下 101010 那个键就可以 format 啦

你能说一下你具体遇到了什么问题吗?

Dear Admin: thank you for your formatting. Conrad,就是在view里导入utils里的类时用from utils import *时会提示标题的错误.但是不影响使用。 其实我是在程序中发现了一个bug想要解决.才一步一步的查到这里,今天突然发现那个错误不是这里导致的。就在你刚回复的另一个帖子里,我发现了调用微信接口的这套程序在添加自定义菜单时总是不成功,查看log发现是500错.可是看不到详细信息,所以只能发贴求助,希望你能帮帮我,by the way,加了你qq可是没有回音,不知道还有其它联系方式吗?很对问题需要请教。为盼。

这有可能是因为我们会限制免费用户的 WebApp 对外的沟通。这是因为不这样做的话常常会有人通过我们来发垃圾邮件或者DoS等恶性行为。如果你需要连接微信的 API 的话,我们可以把微信 API 的特定 url 加到我们的免费用户 whitelist 里。

还有,我应该刚在qq加了你。

我认为不是服务器的问题,因为这个程序在本地测试点击修改菜单也没有反应,可是其他的功能如自动回复可以用,所以觉得不是API的问题,也许是程序哪里没有调试通

群里有人说是一个缓存token的表的问题,用memcached能搞定,不知道pythonanywhere支不支持memcached

我想应该不是这个问题,因为我们不会为你的 token 做任何的缓存。这纯碎是一个 django 的问题。我们继续在 qq 聊

thank you for your help, QQchat