+
+
+
diff --git a/tpl/item/belongitemlist.html b/tpl/item/belongitemlist.html
new file mode 100644
index 0000000..1c1bd20
--- /dev/null
+++ b/tpl/item/belongitemlist.html
@@ -0,0 +1,25 @@
+{% load i18n %}
+
diff --git a/tpl/item/create.html b/tpl/item/create.html
new file mode 100644
index 0000000..6a06125
--- /dev/null
+++ b/tpl/item/create.html
@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}发布信息{% else %}New Post{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+ {% if tagname %}
+
+ {% endif %}
+
+ {% endif %}
+{% endblock %}
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/item/index.html b/tpl/item/index.html
new file mode 100644
index 0000000..8b69a76
--- /dev/null
+++ b/tpl/item/index.html
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}我的分享{% else %}My Post{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+ {% include "item/itemlist.html" %}
+ {% include "item/belongitemlist.html" %}
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/item/itemline.html b/tpl/item/itemline.html
new file mode 100644
index 0000000..79c8c15
--- /dev/null
+++ b/tpl/item/itemline.html
@@ -0,0 +1,35 @@
+{% load i18n %}
+
diff --git a/tpl/item/itemlist.html b/tpl/item/itemlist.html
new file mode 100644
index 0000000..d081271
--- /dev/null
+++ b/tpl/item/itemlist.html
@@ -0,0 +1,25 @@
+{% load i18n %}
+
diff --git a/tpl/item/link.html b/tpl/item/link.html
new file mode 100644
index 0000000..083365f
--- /dev/null
+++ b/tpl/item/link.html
@@ -0,0 +1,115 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}链接{% else %}Links{% endif %} - {% endblock %}
+
+{% block content %}
+
+{% endblock %}
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/item/update.html b/tpl/item/update.html
new file mode 100644
index 0000000..4ea5206
--- /dev/null
+++ b/tpl/item/update.html
@@ -0,0 +1,72 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}更新信息{% else %}Update Post{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+ {% if item %}
+
+
+
+ {% endif %}
+{% endblock %}
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/item/view.html b/tpl/item/view.html
new file mode 100644
index 0000000..e21e871
--- /dev/null
+++ b/tpl/item/view.html
@@ -0,0 +1,336 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% if item %}{{ item.title }}{% else %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}页面不存在{% else %}Page Not Found{% endif %}{% endif %} - {% endblock %}
+
+{% block content %}
+
+ {% if item %}
+
+
+
+ {% if item.user.username == user.username %}
+
+ {% csrf_token %}
+
+
+
+ {% endif %}
+
+ {% if item.user.username == user.username %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}编辑话题{% else %}Edit Tags{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}更新信息{% else %}Update Post{% endif %}
+ {% endif %}
+ {% if user.id == 1 and item.status != 'private' %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}隐藏信息{% else %}Hide Post{% endif %}
+ {% endif %}
+
+
+
+ {% if item.user.username == user.username %}
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}更新信息{% else %}Update Post{% endif %}
+
+
+ {% csrf_token %}
+ {% if form.content.value %}{{ form.content.value }}{% else %}{{ item.itemcontent_set.last.content }}{% endif %}
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}取消{% else %}Cancel{% endif %}
+
+ {% endif %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}评论{% else %}Comment{% endif %}
+
+
+ {% if user.is_authenticated %}
+ {{ form.content.errors }}{{ form.file.errors }}
+
+ {% else %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}或{% else %}or{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}注册{% else %}Sign up{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}以参与评论。{% else %}to post comment.{% endif %}
+
+ {% endif %}
+
+ {% else %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}抱歉,页面不存在。{% else %}Page Not Found.{% endif %}
+ {% endif %}
+
+{% endblock %}
+
+{% block sidebar %}
+
+{% endblock %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/main/app.html b/tpl/main/app.html
new file mode 100644
index 0000000..8606778
--- /dev/null
+++ b/tpl/main/app.html
@@ -0,0 +1,400 @@
+
+
+
+
消息 - Hulu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tpl/main/index.html b/tpl/main/index.html
new file mode 100644
index 0000000..35d42a7
--- /dev/null
+++ b/tpl/main/index.html
@@ -0,0 +1,198 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% endblock %}
+
+{% block content %}
+
+
+
+ {% for item in items %}
+ {% include "item/itemline.html" %}
+ {% endfor %}
+ {% if pitems.paginator.num_pages > 1 %}
+
+ {% elif request.user.id == 1 and getnews %}
+
+ {% endif %}
+
+
+{% endblock %}
+
+{% block sidebar %}
+
+{% endblock %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/other/coin.html b/tpl/other/coin.html
new file mode 100644
index 0000000..40aae87
--- /dev/null
+++ b/tpl/other/coin.html
@@ -0,0 +1,293 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}虚拟数字货币管理{% else %}Cryptocurrency Manage{% endif %} - {% endblock %}
+{% block extra_head %}
+
+{% endblock %}
+{% block content %}
+
+
+
币种
+
持有
+
单价
+
价值
+
操作
+
+
+
+
+
+
+{% endblock %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/other/jk.html b/tpl/other/jk.html
new file mode 100644
index 0000000..5c15773
--- /dev/null
+++ b/tpl/other/jk.html
@@ -0,0 +1,88 @@
+
+
+
+
+
远程
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Play
+
刷新
+
{{ mtime }}
+
+
+
+
+
+
diff --git a/tpl/other/ttt.html b/tpl/other/ttt.html
new file mode 100644
index 0000000..e732d81
--- /dev/null
+++ b/tpl/other/ttt.html
@@ -0,0 +1,450 @@
+
+
+
+
+
Tic Tac Toe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tpl/registration/logged_out.html b/tpl/registration/logged_out.html
new file mode 100644
index 0000000..f4beaaa
--- /dev/null
+++ b/tpl/registration/logged_out.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}退出成功{% else %}Sign out Success{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}退出成功。{% else %}Sign out Success.{% endif %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %}
+
+{% endblock %}
diff --git a/tpl/registration/login.html b/tpl/registration/login.html
new file mode 100644
index 0000000..ffed991
--- /dev/null
+++ b/tpl/registration/login.html
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %} {{ error }}
+ {% if form.errors %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}请填写正确的账号和密码{% else %}Please check your Account and Password{% endif %}
+ {% endif %}
+
+ {% csrf_token %}
+
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}忘记密码?{% else %}Forgot Password?{% endif %} - {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}没有帐号?{% else %}No Account Yet?{% endif %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}现在注册{% else %}Sign up Now{% endif %}
+
+
+
+{% endblock %}
diff --git a/tpl/registration/password_change_done.html b/tpl/registration/password_change_done.html
new file mode 100644
index 0000000..96d4f9f
--- /dev/null
+++ b/tpl/registration/password_change_done.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码修改成功{% else %}Password Changed Successfully{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码修改成功。{% else %}Password Changed Successfully.{% endif %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}返回我的信息{% else %}Back to My Settings{% endif %}
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/registration/password_change_form.html b/tpl/registration/password_change_form.html
new file mode 100644
index 0000000..73fe542
--- /dev/null
+++ b/tpl/registration/password_change_form.html
@@ -0,0 +1,26 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}修改密码{% else %}Change Password{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}修改密码{% else %}Change Password{% endif %}
+ {% if user.userprofile.openid %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}您使用的是第三方帐号登录。{% else %}You Signed in with OAUTH.{% endif %}
+ {% else %}
+ {% if form.errors %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}请填写正确的密码{% else %}Please check your Password{% endif %}
+ {% endif %}
+
+ {% csrf_token %}
+
+
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}取消{% else %}Cancel{% endif %}
+
+ {% endif %}
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/registration/password_reset_complete.html b/tpl/registration/password_reset_complete.html
new file mode 100644
index 0000000..09b9a8b
--- /dev/null
+++ b/tpl/registration/password_reset_complete.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码重置成功{% else %}Password Reset Successfully{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码重置成功。{% else %}Password Reset Successfully.{% endif %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %}
+
+{% endblock %}
diff --git a/tpl/registration/password_reset_confirm.html b/tpl/registration/password_reset_confirm.html
new file mode 100644
index 0000000..681ad28
--- /dev/null
+++ b/tpl/registration/password_reset_confirm.html
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}重置密码{% else %}Reset Password{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}重置密码{% else %}Reset Password{% endif %}
+ {% if form.errors %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}请填写正确的密码{% else %}Please check your Password{% endif %}
+ {% endif %}
+ {% if form %}
+
+ {% csrf_token %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码:{% else %}New Password: {% endif %}{{ form.new_password1 }}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}重复:{% else %}New Password: {% endif %}{{ form.new_password2 }}
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}取消{% else %}Cancel{% endif %}
+
+ {% else %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}链接已失效。{% else %}The link is expired.{% endif %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}返回{% else %}Back{% endif %}
+ {% endif %}
+
+{% endblock %}
diff --git a/tpl/registration/password_reset_done.html b/tpl/registration/password_reset_done.html
new file mode 100644
index 0000000..97bba32
--- /dev/null
+++ b/tpl/registration/password_reset_done.html
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}找回密码{% else %}Reset Password{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码重置链接已发送至您的注册邮箱,请查收。{% else %}The Password Reset link has been sent to your Email, Please check it.{% endif %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}登录{% else %}Sign in{% endif %}
+
+{% endblock %}
diff --git a/tpl/registration/password_reset_email.html b/tpl/registration/password_reset_email.html
new file mode 100644
index 0000000..95f4b5e
--- /dev/null
+++ b/tpl/registration/password_reset_email.html
@@ -0,0 +1,5 @@
+{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}您的账号:{% else %}your Account: {% endif %}{{ user.get_username }}
+{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}点击以下链接重置您的密码:{% else %}Click the link below to Reset your Password:{% endif %}
+{% block reset_link %}
+{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}
+{% endblock %}
diff --git a/tpl/registration/password_reset_form.html b/tpl/registration/password_reset_form.html
new file mode 100644
index 0000000..4f857d4
--- /dev/null
+++ b/tpl/registration/password_reset_form.html
@@ -0,0 +1,28 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}找回密码{% else %}Reset Password{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}找回密码{% else %}Reset Password{% endif %}
+
+ {% csrf_token %}
+
+ {% if form.email.errors %}
+
+ {% if form.email.value %}
+ {% if 'Enter a valid email address.' in form.email.errors %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}邮箱输入错误{% else %}Email is error{% endif %}
+ {% else %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}邮箱输入错误{% else %}This Email has not Signed up{% endif %}
+ {% endif %}
+ {% else %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}邮箱输入错误{% else %}Email is error{% endif %}
+ {% endif %}
+ {% endif %}
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}取消{% else %}Cancel{% endif %}
+
+
+{% endblock %}
diff --git a/tpl/registration/password_reset_subject.txt b/tpl/registration/password_reset_subject.txt
new file mode 100644
index 0000000..a6ee484
--- /dev/null
+++ b/tpl/registration/password_reset_subject.txt
@@ -0,0 +1 @@
+{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}密码重置{% else %}Reset Password{% endif %}
diff --git a/tpl/tag/index.html b/tpl/tag/index.html
new file mode 100644
index 0000000..c51e161
--- /dev/null
+++ b/tpl/tag/index.html
@@ -0,0 +1,65 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}更多话题{% else %}Tags{% endif %} - {% endblock %}
+
+{% block content %}
+
+{% endblock %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/tag/view.html b/tpl/tag/view.html
new file mode 100644
index 0000000..f6a2226
--- /dev/null
+++ b/tpl/tag/view.html
@@ -0,0 +1,93 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% if tag %}{{ tag.name }}{% else %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}页面不存在{% else %}Page Not Found{% endif %}{% endif %} - {% endblock %}
+
+{% block content %}
+
+
+
+
+ {% for item in items %}
+ {% include "item/itemline.html" %}
+ {% endfor %}
+ {% if items.paginator.num_pages > 1 %}
+
+ {% endif %}
+
+
+{% endblock %}
+
+{% block sidebar %}
+
+{% endblock %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/tpl/user/defaultpage.html b/tpl/user/defaultpage.html
new file mode 100644
index 0000000..1c255ce
--- /dev/null
+++ b/tpl/user/defaultpage.html
@@ -0,0 +1,39 @@
+{% extends "base.html" %}
+
+{% block title %}{% if viewuser %}{% if viewuser.userprofile.name %}{{ viewuser.userprofile.name }}{% else %}{{ viewuser.username }}{% endif %}{% else %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}页面不存在{% else %}Page Not Found{% endif %}{% endif %} - {% endblock %}
+
+{% block content %}
+
+ {% if viewuser %}
+
+
+ {% if user.is_authenticated %}
+ {% if request.user == viewuser %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}完善资料{% else %}Update Settings{% endif %}
+ {% else %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}发送消息{% else %}Send Message{% endif %}
+
+
+ {% csrf_token %}
+
+
+
+ {% endif %}
+ {% endif %}
+
+
{{ viewuser.userprofile.profile }}
+
+
+ {% include "item/itemlist.html" %}
+ {% include "item/belongitemlist.html" %}
+ {% else %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}抱歉,页面不存在。{% else %}Page Not Found.{% endif %}
+ {% endif %}
+
+{% endblock %}
diff --git a/tpl/user/feedback.html b/tpl/user/feedback.html
new file mode 100644
index 0000000..ae23e17
--- /dev/null
+++ b/tpl/user/feedback.html
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}发送私信{% else %}Send Message{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}发送私信{% else %}Send Message{% endif %}
+ {% if submit %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}发送成功,多谢您的关注。{% else %}Send Successfully, Thank you.{% endif %}
+ {% else %}
+
+ {% csrf_token %}
+
+
+
+
+
+ {% endif %}
+
+{% endblock %}
diff --git a/tpl/user/index.html b/tpl/user/index.html
new file mode 100644
index 0000000..532a6da
--- /dev/null
+++ b/tpl/user/index.html
@@ -0,0 +1,25 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}我的资料{% else %}My Settings{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}我的资料{% else %}My Settings{% endif %}
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}我的分享{% else %}My Post{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}完善资料{% else %}Update Settings{% endif %}
+
+ {% if not user.userprofile.openid %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}修改密码{% else %}Change Password{% endif %} {% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}退出登录{% else %}Sign out{% endif %}
+
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}帐号:{% else %}Account: {% endif %}{{ user.username }}
+ {% if not user.userprofile.openid %}
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}邮箱:{% else %}Email: {% endif %}{{ user.email }}
{% endif %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}签名:{% else %}Name: {% endif %}{{ user.userprofile.info }}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}简介:{% else %}Bio: {% endif %} {{ user.userprofile.profile }}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}注册于{{ user.userprofile.create|date:'Y年m月d日' }}{% else %}Sign up @ {{ user.userprofile.create|date:'Y-m-d' }}{% endif %}
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/user/list.html b/tpl/user/list.html
new file mode 100644
index 0000000..815ee72
--- /dev/null
+++ b/tpl/user/list.html
@@ -0,0 +1,54 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}用户列表{% else %}User List{% endif %} - {% endblock %}
+
+{% block content %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}用户列表{% else %}User List{% endif %}
+
+ {% for user in users %}
+ {% if user.userprofile %}
+
+ {% endif %}
+ {% endfor %}
+ {% if users.paginator.num_pages > 1 %}
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/tpl/user/notify.html b/tpl/user/notify.html
new file mode 100644
index 0000000..e6e44cf
--- /dev/null
+++ b/tpl/user/notify.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}通知中心{% else %}Notify{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}通知中心{% else %}Notify{% endif %}
+ {% if notify %}
+ {% for i in notify %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}您发布的{% else %}Your Post{% endif %} {% with i.item.belong.all|first as belong %}{% with belong.itemcontent_set.all|first as belongcontent %}{{ belongcontent.content|slice:'30' }}...{% endwith %} {% endwith %} {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}有了{% else %}has{% endif %} {{ i.item.user.username }} {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}的新回应:{% else %}'s new comment: {% endif %}{% with i.item.itemcontent_set.all|first as itemcontent %}{{ itemcontent.content|slice:'30' }}...{% endwith %}
+ {% endfor %}
+ {% else %}
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}暂无通知。{% else %}No Notify Yet.{% endif %}
+ {% endif %}
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/user/page.html b/tpl/user/page.html
new file mode 100644
index 0000000..27b8963
--- /dev/null
+++ b/tpl/user/page.html
@@ -0,0 +1 @@
+{{ user.userprofile.page|safe }}
\ No newline at end of file
diff --git a/tpl/user/settings.html b/tpl/user/settings.html
new file mode 100644
index 0000000..14590f8
--- /dev/null
+++ b/tpl/user/settings.html
@@ -0,0 +1,26 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}完善资料{% else %}Update Settings{% endif %} - {% endblock %}
+
+{% block content %}
+ {% if user.is_authenticated %}
+
+
{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}完善资料{% else %}Update Settings{% endif %}
+
+
+ {% csrf_token %}
+
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}提示:图片会被自动压缩{% else %}Tips: Avatar will be compressed.{% endif %}
+
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}帐号:{% else %}Account: {% endif %}{{ user.username }}
+ {% if not user.userprofile.openid %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}邮箱:{% else %}Email: {% endif %}{{ user.email }}
{% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}签名:{% else %}Name: {% endif %}
+ {% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}简介:{% else %}Bio: {% endif %}{{ user.userprofile.profile }}
+
+
+ {% if prev == 'signup' %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}跳过{% else %}Skip{% endif %} {% else %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}取消{% else %}Cancel{% endif %} {% endif %}
+
+
+ {% endif %}
+{% endblock %}
diff --git a/tpl/user/signup.html b/tpl/user/signup.html
new file mode 100644
index 0000000..0862746
--- /dev/null
+++ b/tpl/user/signup.html
@@ -0,0 +1,56 @@
+{% extends "base.html" %}
+
+{% block title %}{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}注册{% else %}Sign up{% endif %} - {% endblock %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/tpl/widget/about.html b/tpl/widget/about.html
new file mode 100644
index 0000000..335594c
--- /dev/null
+++ b/tpl/widget/about.html
@@ -0,0 +1,9 @@
+
diff --git a/tpl/widget/tag.html b/tpl/widget/tag.html
new file mode 100644
index 0000000..eff7de4
--- /dev/null
+++ b/tpl/widget/tag.html
@@ -0,0 +1,16 @@
+{% if tags %}
{% endif %}
diff --git a/tpl/widget/wxpay.html b/tpl/widget/wxpay.html
new file mode 100644
index 0000000..1aea8a2
--- /dev/null
+++ b/tpl/widget/wxpay.html
@@ -0,0 +1,7 @@
+
diff --git a/user/__init__.py b/user/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/user/__init__.pyc b/user/__init__.pyc
new file mode 100644
index 0000000..20f6b8b
Binary files /dev/null and b/user/__init__.pyc differ
diff --git a/user/forms.py b/user/forms.py
new file mode 100644
index 0000000..052439e
--- /dev/null
+++ b/user/forms.py
@@ -0,0 +1,40 @@
+from django import forms
+from django.contrib.auth.models import User
+from django.contrib.auth.forms import UserCreationForm
+from user.models import *
+from django.utils import timezone
+
+class UserCreationForm(UserCreationForm):
+ username = forms.CharField(min_length=3)
+ email = forms.EmailField(required=True)
+
+ class Meta:
+ model = User
+ fields = ('username', 'email', 'password1', 'password2', 'last_login')
+
+class UserProfileForm(forms.ModelForm):
+ info = forms.CharField(required=False, max_length=255)
+ profile = forms.CharField(required=False, widget=forms.Textarea)
+ page = forms.CharField(required=False, widget=forms.Textarea)
+ avatar = forms.FileField(required=False)
+
+ class Meta:
+ model = UserProfile
+ fields = ('info', 'profile', 'page', 'avatar')
+
+ def clean_avatar(self):
+ avatar = self.cleaned_data['avatar']
+ if avatar:
+ try:
+ if avatar.content_type.split('/')[0] != 'image':
+ return None
+ if avatar._size > 2 * 1024 * 1024:
+ #raise ValidationError("Image file too large ( > 200KB ).")
+ return None
+ else:
+ return avatar
+ except:
+ return None
+ else:
+ #raise ValidationError("Couldn't read uploaded image.")
+ return None
diff --git a/user/forms.pyc b/user/forms.pyc
new file mode 100644
index 0000000..f49d217
Binary files /dev/null and b/user/forms.pyc differ
diff --git a/user/models.py b/user/models.py
new file mode 100644
index 0000000..1f6c101
--- /dev/null
+++ b/user/models.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+import sys
+reload(sys)
+sys.setdefaultencoding('utf8')
+
+from django.db import models
+
+# Create your models here.
+from django.contrib.auth.models import User
+from django.core.files.storage import FileSystemStorage
+from django.conf import settings
+import os
+from item.models import *
+from django.db.models import Q
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from item.__init__ import *
+
+User._meta.get_field('email')._unique = True
+
+def avatar_file(instance, filename):
+ return os.path.join('avatar', str(instance.user.username) + '.png')
+
+def get_item_by_user(user, request):
+ try:
+ if request.user.is_authenticated():
+ items = Item.objects.select_related('user').filter(user=user).filter(useritemrelationship__isnull=True).filter(Q(belong__isnull=True)).filter(~Q(status__exact='private') | Q(user=request.user)).order_by('-id').prefetch_related('itemcontent_set')
+ else:
+ items = Item.objects.select_related('user').filter(user=user).filter(useritemrelationship__isnull=True).filter(Q(belong__isnull=True)).filter(~Q(status__exact='private')).order_by('-id').prefetch_related('itemcontent_set')
+ items = sorted(items, key=lambda item:item.id, reverse=True)
+
+ subitems = Item.objects.filter(user=user).filter(useritemrelationship__isnull=True).filter(Q(belong__isnull=False)).order_by('-id').prefetch_related('itemcontent_set')
+ belongitems = []
+ for subitem in subitems:
+ rootitems = subitem.get_root_items()
+ for rootitem in rootitems:
+ #过滤掉重复的、自己发的、私有的信息
+ if rootitem not in belongitems and rootitem.user != user and rootitem.status != 'private':
+ belongitems.append(rootitem)
+ belongitems = sorted(belongitems, key=lambda belongitem:belongitem.id, reverse=True)
+
+ for item in items:
+ itemcontent = item.itemcontent_set.all()
+ if itemcontent:
+ item.create = itemcontent[0].create
+ if itemcontent[0].content:
+ item.title = itemcontent[0].content.strip().splitlines()[0]
+ else:
+ contentattachment = itemcontent[0].contentattachment_set.all()
+ if contentattachment:
+ item.title = contentattachment[0].title
+ else:
+ item.title = str(item.id)
+
+ for item in belongitems:
+ itemcontent = item.itemcontent_set.all()
+ if itemcontent:
+ item.create = itemcontent[0].create
+ if itemcontent[0].content:
+ item.title = itemcontent[0].content.strip().splitlines()[0]
+ else:
+ contentattachment = itemcontent[0].contentattachment_set.all()
+ if contentattachment:
+ item.title = contentattachment[0].title
+ else:
+ item.title = str(item.id)
+
+ items = sort_items(items, request.GET.get('page'))
+ belongitems = sort_items(belongitems, request.GET.get('page'))
+ except Item.DoesNotExist:
+ items = None
+ belongitems = None
+
+ return items, belongitems
+
+class OverwriteStorage(FileSystemStorage):
+ def get_available_name(self, name, max_length=None):
+ if self.exists(name):
+ os.remove(os.path.join(settings.MEDIA_ROOT, name))
+ return name
+
+class UserRelationship(models.Model):
+ user = models.ForeignKey(User)
+ type = models.CharField(max_length=30)
+
+class UserProfile(models.Model):
+ user = models.OneToOneField(User)
+ create = models.DateTimeField(auto_now_add=True)
+ status = models.CharField(max_length=30)
+ credit = models.BigIntegerField(default=0)
+ openid = models.CharField(max_length=128)
+ info = models.CharField(max_length=255)
+ profile = models.TextField()
+ page = models.TextField()
+ avatar = models.FileField(storage=OverwriteStorage(), upload_to=avatar_file)
+ userrelationship = models.ManyToManyField(UserRelationship)
+
+class UserNotify(models.Model):
+ user = models.ForeignKey(User)
+ created = models.DateTimeField(auto_now_add=True)
+ status = models.CharField(max_length=30)
+ type = models.CharField(max_length=30)
+ item = models.ForeignKey(Item)
diff --git a/user/models.pyc b/user/models.pyc
new file mode 100644
index 0000000..bba7c5e
Binary files /dev/null and b/user/models.pyc differ
diff --git a/user/urls.py b/user/urls.py
new file mode 100644
index 0000000..c59cbb4
--- /dev/null
+++ b/user/urls.py
@@ -0,0 +1,22 @@
+from django.conf.urls import url
+
+from user import views
+from django.contrib.auth import views as authviews
+
+urlpatterns = [
+ url(r'^$', views.Main, name='index'),
+ url(r'^signup/$', views.Signup, name='signup'),
+ url(r'^login/$', views.Login, name='login'),
+ url(r'^logout/$', authviews.logout, {'next_page': '/'}, name='logout'),
+ url(r'^settings/$', views.Settings, name='settings'),
+ url(r'^notify/$', views.Notify, name='notify'),
+ url(r'^password_change/$', authviews.password_change, name='password_change'),
+ url(r'^password_change_done/$', authviews.password_change_done, name='password_change_done'),
+ url(r'^password_reset/$', authviews.password_reset, name='password_reset'),
+ url(r'^password_reset_done/$', authviews.password_reset_done, name='password_reset_done'),
+ url(r'^password_reset_confirm/(?P
[0-9A-Za-z]+)-(?P.+)/$', authviews.password_reset_confirm, name='password_reset_confirm'),
+ #url(r'^password_reset_confirm/(?P[0-9A-Za-z_\-]+)-(?P.+)/$', 'django.contrib.auth.views.password_reset_confirm', name='password_reset_confirm'),
+ url(r'^password_reset_complete/$', authviews.password_reset_complete, name='password_reset_complete'),
+ url(r'^feedback/$', views.Feedback, name='feedback'),
+ url(r'^list/$', views.List, name='list'),
+]
diff --git a/user/urls.pyc b/user/urls.pyc
new file mode 100644
index 0000000..e6cfb19
Binary files /dev/null and b/user/urls.pyc differ
diff --git a/user/views.py b/user/views.py
new file mode 100644
index 0000000..15735f3
--- /dev/null
+++ b/user/views.py
@@ -0,0 +1,606 @@
+# -*- coding: utf-8 -*-
+import sys
+reload(sys)
+sys.setdefaultencoding('utf8')
+# Create your views here.
+
+from django.template import RequestContext
+from django.http import HttpResponse
+from django.shortcuts import redirect, render
+from datetime import datetime, timedelta
+from django.utils import timezone
+import urllib2
+import json
+import time
+from django.contrib.auth.models import User
+from django.contrib.auth import *
+from django.contrib.auth.forms import *
+from django.core.mail import send_mail
+from hulu import *
+from main.__init__ import *
+from user.models import *
+from user.forms import *
+from item.models import *
+from item.forms import *
+from django.db.models import Q
+from django.forms.utils import ErrorList
+from django.views.decorators import csrf
+import os
+from django.utils.html import escape
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+
+if 'VCAP_SERVICES' in os.environ:
+ vcap = json.loads(os.environ['VCAP_SERVICES'])
+ if 'Object-Storage' in vcap:
+ ocp = vcap['Object-Storage'][0]['credentials']
+ import swiftclient
+ OC = swiftclient.Connection(key=ocp['password'], authurl=ocp['auth_url'] + '/v3', auth_version='3', os_options={'project_id': ocp['projectId'], 'user_id': ocp['userId'], 'region_name': ocp['region']})
+
+def Main(request):
+ user = request.user
+ if user.is_authenticated():
+ content = {}
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success',
+ 'user': {
+ 'username': user.username,
+ 'email': user.email,
+ 'name': user.userprofile.info,
+ 'avatar': (user.userprofile.openid and '//' in str(user.userprofile.avatar)) and str(user.userprofile.avatar) or ((user.userprofile.avatar) and '/s/' + str(user.userprofile.avatar) or '/s/avatar/n.png'),
+ 'page': user.userprofile.page,
+ 'create': str(user.userprofile.create)
+ }
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'user/index.html', content)
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return redirectlogin(request)
+
+def Signup(request):
+ next = None
+ if request.GET.get('next'):
+ next = request.META['QUERY_STRING'].split('next=')[1]
+ if request.GET.get('next'):
+ if request.GET.get('next')[0] != '/':
+ return redirect('/u/signup/')
+ else:
+ nextpath = request.GET.get('next').split('?')[0]
+ if nextpath[0] != '/' or nextpath in ['', '/', '/u/login/', '/u/signup/']:
+ return redirect('/u/signup/')
+ if request.user.is_authenticated():
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+ if request.method == 'GET':
+ if request.GET.get('type') == 'json':
+ content = {
+ 'csrf_token': unicode(csrf(request)['csrf_token'])
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'user/signup.html', {})
+ if request.method == 'POST':
+ form = UserCreationForm(request.POST)
+ if form.is_valid():
+ newuser = form.save(commit=False)
+ newuser.last_login = timezone.now()
+ newuser.save()
+
+ email = form.cleaned_data['email']
+ username = form.cleaned_data['username']
+ password = form.cleaned_data['password1'] = form.cleaned_data['password2']
+ user = User.objects.get(username=username)
+ userprofile = UserProfile(user=user)
+ userprofile.save()
+ user = authenticate(username=username, password=password)
+ login(request, user)
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect('/u/settings/?prev=signup&next=' + next)
+ else:
+ return redirect('/u/settings/?prev=signup')
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error',
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'errors': [(k, map(unicode, v)) for k, v in form.errors.items()]
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'user/signup.html', { 'form': form })
+
+def Login(request):
+ next = None
+ if request.GET.get('next'):
+ next = request.META['QUERY_STRING'].split('next=')[1].split("&type=qq")[0]
+
+ if request.GET.get('type') == 'qq':
+ qq_app_id = os.environ['qq_app_id']
+ qq_app_key = os.environ['qq_app_key']
+ if request.GET.get('code'):
+ openid = None
+ try:
+ access_token = str(urllib2.urlopen('https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=' + qq_app_id + '&client_secret=' + qq_app_key + '&code=' + request.GET.get('code').strip() + '&redirect_uri=' + urllib2.quote('http://' + request.get_host() + '/u/login/?type=qq')).read().split('&')[0].split('access_token=')[1]).strip()
+ openid = str(urllib2.urlopen('https://graph.qq.com/oauth2.0/me?access_token=' + access_token).read().split('"openid":"')[1].split('"')[0])
+ except:
+ pass
+ if openid:
+ try:
+ user = User.objects.get(userprofile__openid='QQ' + openid)
+ except User.DoesNotExist:
+ user = None
+ if user:
+ if user.is_active:
+ user.backend = 'django.contrib.auth.backends.ModelBackend'
+ login(request, user)
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+ else:
+ if next:
+ return redirect('/u/login/?next=' + next)
+ else:
+ return redirect('/u/login/')
+ else:
+ try:
+ user_info = str(urllib2.urlopen('https://graph.qq.com/user/get_user_info?access_token=' + access_token + '&oauth_consumer_key=' + qq_app_id + '&openid=' + openid).read()).strip()
+ user_info = json.loads(user_info)
+
+ def getrandomusername(randomusernameplus):
+ randomusernametime = 'QQ' + str(datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
+ if randomusernameplus == 0:
+ try:
+ if User.objects.get(username=randomusernametime):
+ randomusernameplus += 1
+ return getrandomusername(randomusernameplus)
+ except User.DoesNotExist:
+ return randomusernametime
+ else:
+ try:
+ if User.objects.get(username=randomusernametime + str(randomusernameplus)):
+ randomusernameplus += 1
+ return getrandomusername(randomusernameplus)
+ except User.DoesNotExist:
+ return randomusernametime + str(randomusernameplus)
+
+ user = User.objects.create_user(username=getrandomusername(0), email=openid + '@qq.com', last_login = timezone.now())
+ user.save()
+ userprofile = UserProfile(user=user)
+ userprofile.openid = 'QQ' + openid
+ userprofile.info = str(user_info['nickname'].encode('utf-8', 'ignore')).strip()
+ userprofile.avatar = str(user_info['figureurl_qq_2'].strip().replace('http://', 'https://'))
+ userprofile.save()
+ user.backend = 'django.contrib.auth.backends.ModelBackend'
+ login(request, user)
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+ except:
+ if next:
+ return redirect('/u/login/?next=' + next)
+ else:
+ return redirect('/u/login/')
+ else:
+ if next:
+ return redirect('/u/login/?next=' + next)
+ else:
+ return redirect('/u/login/')
+ else:
+ if next:
+ return redirect('https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + qq_app_id + '&redirect_uri=' + urllib2.quote('http://' + request.get_host() + '/u/login/?next=' + next + '&type=qq'))
+ else:
+ return redirect('https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + qq_app_id + '&redirect_uri=' + urllib2.quote('http://' + request.get_host() + '/u/login/?type=qq'))
+
+ if request.GET.get('next'):
+ if request.GET.get('next')[0] != '/':
+ return redirect('/u/login/')
+ else:
+ nextpath = request.GET.get('next').split('?')[0]
+ if nextpath[0] != '/' or nextpath in ['', '/', '/a/', '/u/login/', '/u/signup/']:
+ return redirect('/u/login/')
+ if request.user.is_authenticated():
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+ if request.method == 'GET':
+ if request.GET.get('type') == 'json':
+ content = {
+ 'csrf_token': unicode(csrf(request)['csrf_token'])
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'registration/login.html', { 'next': next })
+ if request.method == 'POST':
+ form = AuthenticationForm(data=request.POST)
+ if form.is_valid():
+ username = form.cleaned_data['username']
+ password = form.cleaned_data['password']
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ if user.is_active:
+ login(request, user)
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error',
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'errors': [(k, map(unicode, v)) for k, v in form.errors.items()]
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'registration/login.html', { 'form': form, 'next': next })
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error',
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'errors': [(k, map(unicode, v)) for k, v in form.errors.items()]
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'registration/login.html', { 'form': form, 'next': next })
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error',
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'errors': [(k, map(unicode, v)) for k, v in form.errors.items()]
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return render(request, 'registration/login.html', { 'form': form, 'next': next })
+
+def Logout(request):
+ next = None
+ if request.GET.get('next'):
+ next = request.META['QUERY_STRING'].split('next=')[1]
+ if request.GET.get('next')[0] != '/':
+ return redirect('/u/login/')
+ else:
+ nextpath = request.GET.get('next').split('?')[0]
+ if nextpath[0] != '/' or nextpath in ['', '/', '/u/login/', '/u/signup/']:
+ return redirect('/u/login/')
+ logout(request)
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect(next)
+ else:
+ return redirect('/')
+
+def Settings(request):
+ prev = None
+ if request.GET.get('prev'):
+ prev = request.GET.get('prev')
+ next = None
+ if request.GET.get('next'):
+ next = request.META['QUERY_STRING'].split('next=')[1]
+ nextpath = request.GET.get('next').split('?')[0]
+ if prev and next and (nextpath[0] != '/' or nextpath in['', '/u/login/', '/u/signup/']):
+ return redirect('/u/settings/?prev=' + prev)
+ if request.user.is_authenticated():
+ if request.method == 'GET':
+ if request.GET.get('type') == 'json':
+ content = {
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'prev': prev,
+ 'next': next
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ content = {
+ 'prev': prev,
+ 'next': next
+ }
+ return render(request, 'user/settings.html', content)
+ if request.method == 'POST':
+ userprofile = UserProfile.objects.get(user=request.user)
+ form = UserProfileForm(request.POST, request.FILES, instance=userprofile)
+ if form.is_valid():
+ userprofile = form.save()
+
+ if userprofile.avatar and checkmodule('PIL'):
+ from PIL import Image
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', str(request.user.username) + '.png')
+ if os.path.isfile(avatar_file):
+ avatar = Image.open(avatar_file)
+ max_size = 64
+ if avatar.size[0] > avatar.size[1]:
+ size = (max_size, int(max_size * avatar.size[1] / avatar.size[0]))
+ else:
+ size = (int(max_size * avatar.size[0] / avatar.size[1]), max_size)
+ avatar.thumbnail(size, Image.ANTIALIAS)
+
+ def resize_avatar(avatar, p):
+ avatar_size = os.path.getsize(avatar_file)
+ if avatar_size > 5 * 1024 and avatar.size[0] > 1 and avatar.size[1] > 1:
+ p = p * 0.75
+ avatar.thumbnail([int(p * s) for s in avatar.size], Image.ANTIALIAS)
+ avatar = avatar.resize(size)
+ avatar.save(avatar_file, optimize=True)
+ if os.path.getsize(avatar_file) >= avatar_size:
+ resize_avatar(avatar, p)
+ resize_avatar(avatar, 1)
+
+ if 'VCAP_SERVICES' in os.environ:
+ vcap = json.loads(os.environ['VCAP_SERVICES'])
+ if 'Object-Storage' in vcap:
+ containers = []
+ for container in OC.get_account()[1]:
+ containers.append(container['name'])
+ if 'avatar' not in containers:
+ OC.put_container('avatar')
+ with open(avatar_file, 'r') as os_avatar:
+ #OC.delete_object('avatar', str(request.user.username) + '.png')
+ OC.put_object('avatar', str(request.user.username) + '.png', contents=os_avatar.read(), content_type='image/png')
+ os_avatar.close()
+ os.remove(avatar_file)
+
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'success'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ if next:
+ return redirect(next)
+ else:
+ return redirect(Main)
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error',
+ 'csrf_token': unicode(csrf(request)['csrf_token']),
+ 'errors': [(k, map(unicode, v)) for k, v in form.errors.items()]
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ content = {
+ 'prev': prev,
+ 'next': next,
+ 'form': form
+ }
+ return render(request, 'user/settings.html', content)
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return redirectlogin(request)
+
+def UserPage(request, username):
+ try:
+ user = User.objects.get(username=username)
+ try:
+ userprofile = UserProfile.objects.get(user=user)
+ except UserProfile.DoesNotExist:
+ user = None
+ except User.DoesNotExist:
+ user = None
+
+ items, belongitems = get_item_by_user(user, request)
+
+ if request.GET.get('type') == 'json':
+ if user:
+ content = {
+ 'status': 'success',
+ 'user': {
+ 'username': user.username,
+ 'info': user.userprofile.info,
+ 'avatar': (user.userprofile.openid and '//' in str(user.userprofile.avatar)) and str(user.userprofile.avatar) or ((user.userprofile.avatar) and '/s/' + str(user.userprofile.avatar) or '/s/avatar/n.png'),
+ 'profile': user.userprofile.profile,
+ 'page': user.userprofile.page
+ }
+ }
+ else:
+ content = {
+ 'status': 'error'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ content = {
+ 'viewuser': user,
+ 'items': items,
+ 'belongitems': belongitems
+ }
+ return render(request, 'user/defaultpage.html', content)
+
+def Page(request, username):
+ try:
+ user = User.objects.get(username=username)
+ try:
+ userprofile = UserProfile.objects.get(user=user)
+ except UserProfile.DoesNotExist:
+ user = None
+ except User.DoesNotExist:
+ user = None
+ if request.GET.get('type') == 'json':
+ if user:
+ content = {
+ 'status': 'success',
+ 'user': {
+ 'username': user.username,
+ 'info': user.userprofile.info,
+ 'avatar': (user.userprofile.openid and '//' in str(user.userprofile.avatar)) and str(user.userprofile.avatar) or ((user.userprofile.avatar) and '/s/' + str(user.userprofile.avatar) or '/s/avatar/n.png'),
+ 'profile': user.userprofile.profile,
+ 'page': user.userprofile.page
+ }
+ }
+ else:
+ content = {
+ 'status': 'error'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ content = {
+ 'user': user
+ }
+ if user and user.userprofile.page:
+ return render(request, 'user/page.html', content)
+ else:
+ return render(request, 'user/defaultpage.html', content)
+
+def Notify(request):
+ user = request.user
+ if user.is_authenticated():
+ try:
+ notify = UserNotify.objects.all().filter(user=request.user).order_by('-created')
+ for i in notify:
+ if i.item.get_root_items():
+ i.rootitem = i.item.get_root_items()[0]
+ else:
+ i.rootitem = None
+ except User.DoesNotExist:
+ notify = None
+
+ content = {
+ 'notify': notify
+ }
+ if request.GET.get('type') == 'json':
+ messages = []
+ for i in notify:
+ message = {
+ 'rootitem': {
+ 'id': str(i.rootitem.id)
+ },
+ 'parent': {
+ 'id': str(i.item.belong.all().first().id),
+ 'content': escape(str(i.item.belong.all().first().itemcontent_set.all().first().content.strip().splitlines()[0]))
+ },
+ 'item': {
+ 'id': str(i.item.id),
+ 'content': escape(str(i.item.itemcontent_set.all().first().content.strip().splitlines()[0]).encode('utf-8')),
+ 'user': {
+ 'username': i.item.user.username,
+ 'info': escape(i.item.user.userprofile.info),
+ 'avatar': (i.item.user.userprofile.openid and '//' in str(i.item.user.userprofile.avatar)) and str(i.item.user.userprofile.avatar) or ((i.item.user.userprofile.avatar) and '/s/' + str(i.item.user.userprofile.avatar) or '/s/avatar/n.png'),
+ 'profile': escape(i.item.user.userprofile.profile),
+ 'page': escape(i.item.user.userprofile.page)
+ }
+ },
+ 'created': str(i.created + timedelta(hours=8)),
+ }
+ messages.append(message)
+ content = {
+ 'status': 'success',
+ 'notify': {
+ 'count': len(notify),
+ 'messages': messages
+ }
+ }
+ return jsonp(request, content)
+ return render(request, 'user/notify.html', content)
+ else:
+ if request.GET.get('type') == 'json':
+ content = {
+ 'status': 'error'
+ }
+ return HttpResponse(json.dumps(content, encoding='utf-8', ensure_ascii=False, indent=4), content_type="application/json; charset=utf-8")
+ return redirectlogin(request)
+
+def Feedback(request):
+ if request.method == 'GET':
+ return render(request, 'user/feedback.html', {})
+ if request.method == 'POST':
+ if request.POST.get('feedback'):
+ feedback = request.POST['feedback']
+ try:
+ feedbackuser = ''
+ if request.user.username:
+ feedbackuser = str(request.user.username) + ': '
+ send_mail('Hulu', feedbackuser + feedback, os.environ['system_mail_username'], [os.environ['receive_mail']], fail_silently=False)
+ return render(request, 'user/feedback.html', { 'submit': 'true' })
+ except:
+ return redirect('/u/feedback/')
+ else:
+ return redirect('/u/feedback/')
+
+def List(request):
+ try:
+ users = User.objects.all().order_by('-date_joined')
+ except User.DoesNotExist:
+ users = None
+
+ paginator = Paginator(users, 100)
+ itemlist = []
+ page = request.GET.get('page')
+ try:
+ users = paginator.page(page)
+ except PageNotAnInteger:
+ users = paginator.page(1)
+ except EmptyPage:
+ users = paginator.page(paginator.num_pages)
+
+ content = {
+ 'users': users
+ }
+ return render(request, 'user/list.html', content)
+
+def Avatar(request, avatar):
+ def get_avatar_object():
+ avatar_object = None
+ if 'VCAP_SERVICES' in os.environ:
+ vcap = json.loads(os.environ['VCAP_SERVICES'])
+ if 'Object-Storage' in vcap:
+ container = 'avatar'
+ containers = []
+ try:
+ for ctn in OC.get_account()[1]:
+ containers.append(ctn['name'])
+ if container not in containers:
+ OC.put_container(container)
+ for obj in OC.get_container(container)[1]:
+ if obj['name'] == avatar:
+ avatar_object = OC.get_object(container, avatar)[1]
+ break
+ if not avatar_object:
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', avatar)
+ if not os.path.isfile(avatar_file):
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', 'n.png')
+ avatar_object = open(avatar_file, 'rb').read()
+ except:
+ pass
+ else:
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', avatar)
+ if not os.path.isfile(avatar_file):
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', 'n.png')
+ avatar_object = open(avatar_file, 'rb').read()
+ else:
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', avatar)
+ if not os.path.isfile(avatar_file):
+ avatar_file = os.path.join(settings.MEDIA_ROOT, 'avatar', 'n.png')
+ avatar_object = open(avatar_file, 'rb').read()
+
+ if avatar_object:
+ return avatar_object
+ else:
+ return get_avatar_object()
+
+ return HttpResponse(get_avatar_object(), content_type='image/png')
diff --git a/user/views.pyc b/user/views.pyc
new file mode 100644
index 0000000..74b5777
Binary files /dev/null and b/user/views.pyc differ

+ {% elif 'audio' in attachmentfile.contenttype %} + + {% else %} +({% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}附件{% else %}Attachment{% endif %}) {{ attachmentfile.title }}
+ {% endif %} + {% endfor %} +{% if 'zh' in request.LANGUAGE_CODE or 'zh' in LANGUAGE_CODE %}暂无评论。{% else %}No Comment Yet.{% endif %}
+ {% endif %} +