소스 검색

[fixes] + added frappeclient

version-14
Rushabh Mehta 10 년 전
부모
커밋
2ab10573f6
12개의 변경된 파일266개의 추가작업 그리고 139개의 파일을 삭제
  1. +1
    -1
      frappe/core/doctype/docshare/docshare.json
  2. +10
    -0
      frappe/core/page/data_import_tool/importer.py
  3. +211
    -0
      frappe/frappeclient.py
  4. +2
    -2
      frappe/model/db_query.py
  5. +9
    -46
      frappe/public/css/website.css
  6. +10
    -57
      frappe/public/less/website.less
  7. +3
    -3
      frappe/templates/includes/blog_list.html
  8. +0
    -19
      frappe/templates/pages/blog.html
  9. +1
    -1
      frappe/templates/pages/blog.py
  10. +4
    -4
      frappe/website/doctype/web_page/web_page.py
  11. +13
    -2
      frappe/website/js/website.js
  12. +2
    -4
      frappe/website/template.py

+ 1
- 1
frappe/core/doctype/docshare/docshare.json 파일 보기

@@ -138,7 +138,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-02-06 00:44:40.883188",
"modified": "2015-02-12 11:30:52.968078",
"modified_by": "Administrator",
"module": "Core",
"name": "DocShare",


+ 10
- 0
frappe/core/page/data_import_tool/importer.py 파일 보기

@@ -138,6 +138,15 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
def main_doc_empty(row):
return not (row and ((len(row) > 1 and row[1]) or (len(row) > 2 and row[2])))

users = frappe.db.sql_list("select name from tabUser")
def prepare_for_insert(doc):
# don't block data import if user is not set
# migrating from another system
if not doc.owner in users:
doc.owner = frappe.session.user
if not doc.modified_by in users:
doc.modified_by = frappe.session.user

# header
if not rows:
rows = read_csv_content_from_uploaded_file(ignore_encoding_errors)
@@ -210,6 +219,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
ret.append('Updated row (#%d) %s' % (row_idx + 1, getlink(original.doctype, original.name)))
else:
doc = frappe.get_doc(doc)
prepare_for_insert(doc)
doc.flags.ignore_links = ignore_links
doc.insert()
ret.append('Inserted row (#%d) %s' % (row_idx + 1, getlink(doc.doctype, doc.name)))


+ 211
- 0
frappe/frappeclient.py 파일 보기

@@ -0,0 +1,211 @@
import requests
import json
import frappe

class AuthError(Exception):
pass

class FrappeException(Exception):
pass

class FrappeClient(object):
def __init__(self, url, username, password):
self.session = requests.Session()
self.url = url
self.login(username, password)

def __enter__(self):
return self

def __exit__(self, *args, **kwargs):
self.logout()

def login(self, username, password):
r = self.session.post(self.url, data={
'cmd': 'login',
'usr': username,
'pwd': password
})

if r.json().get('message') == "Logged In":
return r.json()
else:
raise AuthError

def logout(self):
self.session.get(self.url, params={
'cmd': 'logout',
})

def get_list(self, doctype, fields='"*"', filters=None, limit_start=0, limit_page_length=0):
"""Returns list of records of a particular type"""
params = {
"fields": fields,
}
if filters:
params["filters"] = json.dumps(filters)
if limit_page_length:
params["limit_start"] = limit_start
params["limit_page_length"] = limit_page_length
res = self.session.get(self.url + "/api/resource/" + doctype, params=params)
return self.post_process(res)

def insert(self, doc):
res = self.session.post(self.url + "/api/resource/" + doc.get("doctype"),
data={"data":json.dumps(doc)})
return self.post_process(res)

def update(self, doc):
url = self.url + "/api/resource/" + doc.get("doctype") + "/" + doc.get("name")
res = self.session.put(url, data={"data":json.dumps(doc)})
return self.post_process(res)

def bulk_update(self, docs):
return self.post_request({
"cmd": "frappe.client.bulk_update",
"docs": json.dumps(docs)
})

def delete(self, doctype, name):
return self.post_request({
"cmd": "frappe.model.delete_doc",
"doctype": doctype,
"name": name
})

def submit(self, doclist):
return self.post_request({
"cmd": "frappe.client.submit",
"doclist": json.dumps(doclist)
})

def get_value(self, doctype, fieldname=None, filters=None):
return self.get_request({
"cmd": "frappe.client.get_value",
"doctype": doctype,
"fieldname": fieldname or "name",
"filters": json.dumps(filters)
})

def set_value(self, doctype, docname, fieldname, value):
return self.post_request({
"cmd": "frappe.client.set_value",
"doctype": doctype,
"name": docname,
"fieldname": fieldname,
"value": value
})

def cancel(self, doctype, name):
return self.post_request({
"cmd": "frappe.client.cancel",
"doctype": doctype,
"name": name
})

def get_doc(self, doctype, name="", filters=None, fields=None):
params = {}
if filters:
params["filters"] = json.dumps(filters)
if fields:
params["fields"] = json.dumps(fields)

res = self.session.get(self.url + "/api/resource/" + doctype + "/" + name,
params=params)

return self.post_process(res)

def rename_doc(self, doctype, old_name, new_name):
params = {
"cmd": "frappe.client.rename_doc",
"doctype": doctype,
"old_name": old_name,
"new_name": new_name
}
return self.post_request(params)

def migrate_doctype(self, doctype, filters={}):
"""Migrate records from another doctype"""
meta = frappe.get_meta(doctype)
tables = {}
for df in meta.get_table_fields():
print "getting " + df.options
tables[df.fieldname] = self.get_list(df.options, limit_page_length=999999)

# get links
print "getting " + doctype
docs = self.get_list(doctype, limit_page_length=999999, filters=filters)

# build - attach children to parents
if tables:
docs_map = {}
for doc in docs:
docs_map[doc.name] = doc

for fieldname in tables:
for child in tables[fieldname]:
docs_map[child.parent].append(fieldname, child)

print "inserting " + doctype
for doc in docs:
if not frappe.db.exists("User", doc.get("owner")):
frappe.get_doc({"doctype": "User", "email": doc.get("owner"),
"first_name": doc.get("owner").split("@")[0] }).insert()

doc["doctype"] = doctype
frappe.get_doc(doc).insert()

if doctype != "Comment":
self.migrate_doctype("Comment", {"comment_doctype": doctype})

def migrate_single(self, doctype):
doc = self.get_doc(doctype, doctype)
doc = frappe.get_doc(doc)

# change modified so that there is no error
doc.modified = frappe.db.get_single_value(doctype, "modified")
frappe.get_doc(doc).insert()

def get_api(self, method, params={}):
res = self.session.get(self.url + "/api/method/" + method + "/",
params=params)
return self.post_process(res)

def post_api(self, method, params={}):
res = self.session.post(self.url + "/api/method/" + method + "/",
params=params)
return self.post_process(res)

def get_request(self, params):
res = self.session.get(self.url, params=self.preprocess(params))
res = self.post_process(res)
return res

def post_request(self, data):
res = self.session.post(self.url, data=self.preprocess(data))
res = self.post_process(res)
return res

def preprocess(self, params):
"""convert dicts, lists to json"""
for key, value in params.iteritems():
if isinstance(value, (dict, list)):
params[key] = json.dumps(value)

return params

def post_process(self, response):
try:
rjson = response.json()
except ValueError:
print response.text
raise

if rjson and ("exc" in rjson) and rjson["exc"]:
raise FrappeException(rjson["exc"])
if 'message' in rjson:
return rjson['message']
elif 'data' in rjson:
return rjson['data']
else:
return None

+ 2
- 2
frappe/model/db_query.py 파일 보기

@@ -35,8 +35,8 @@ class DatabaseQuery(object):
self.docstatus = docstatus or []
self.group_by = group_by
self.order_by = order_by
self.limit_start = limit_start
self.limit_page_length = limit_page_length
self.limit_start = int(limit_start)
self.limit_page_length = int(limit_page_length)
self.with_childnames = with_childnames
self.debug = debug
self.as_list = as_list


+ 9
- 46
frappe/public/css/website.css 파일 보기

@@ -278,60 +278,23 @@ body {
margin-bottom: 15px;
}
/* post and post list */
.post {
.web-list-item {
padding: 15px 0px;
word-wrap: break-word;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #d1d8dd;
}
.post:first-child {
margin-top: 15px !important;
}
.post .img-responsive {
border-radius: 4px;
}
.post .media-link {
display: block;
min-width: 50px;
min-height: 50px;
}
.post .media-object {
border-radius: 4px;
max-width: 50px;
}
.post .media-heading {
margin-bottom: 12px;
.web-list-item:last-child {
border-bottom: none;
}
.parent-post .post {
border: none;
.web-list-item h3 {
margin: 0 0 5px 0;
}
.child-post {
border: 1px solid #eee;
padding-left: 15px;
background-color: #f8f8f8;
margin-top: 0px;
.web-list-item h3 a {
color: inherit !important;
text-decoration: none;
}
textarea {
resize: vertical;
}
.post-add-textarea {
height: 200px !important;
}
/* needs review */
.btn-small,
.post-editor .btn {
padding: 5px;
font-size: 90%;
}
.btn-right,
.post-editor .btn {
margin-left: 5px;
}
.no-posts {
margin-top: 15px;
}
.full-page {
margin: 30px;
}
.user-profile {
min-height: 50px;
min-width: 70px;


+ 10
- 57
frappe/public/less/website.less 파일 보기

@@ -330,73 +330,26 @@ body {
}

/* post and post list */
.post {
padding: 15px 0px;
word-wrap: break-word;
border-bottom: 1px solid #eee;
}

.post:first-child {
margin-top: 15px !important;
.web-list-item {
padding: 15px 0px;
border-bottom: 1px solid @border-color;
}

.post .img-responsive {
border-radius: 4px;
.web-list-item:last-child {
border-bottom: none;
}

.post .media-link {
display: block;
min-width: 50px;
min-height: 50px;
.web-list-item h3 {
margin: 0 0 5px 0;
}

.post .media-object {
border-radius: 4px;
max-width: 50px;
}

.post .media-heading {
margin-bottom: 12px;
}

.parent-post .post {
border: none;
}

.child-post {
border: 1px solid #eee;
padding-left: 15px;
background-color: #f8f8f8;
margin-top: 0px;
.web-list-item h3 a {
color: inherit !important;
text-decoration: none;
}

textarea {
resize: vertical;
}

.post-add-textarea {
height: 200px !important;
}

/* needs review */

.btn-small, .post-editor .btn {
padding: 5px;
font-size: 90%;
}

.btn-right, .post-editor .btn {
margin-left: 5px;
}

.no-posts {
margin-top: 15px;
}

.full-page {
margin: 30px;
}

.user-profile {
min-height: 50px;
min-width: 70px;


+ 3
- 3
frappe/templates/includes/blog_list.html 파일 보기

@@ -1,10 +1,10 @@
{% for post in posts %}
<div class="row blog-post-preview border-bottom">
<div class="col-md-2 text-center text-muted">
<div class="row web-list-item">
<div class="col-xs-2 text-center text-muted">
<h1 class="blog-day" style="margin: 0px;">{{ post.day }}</h1>
<div class="small">{{ post.month }} {{ post.year }}</div>
</div>
<div class="col-md-10">
<div class="col-xs-10">
<h3><a href="/{{ post.page_name }}">{{ post.title }}</a></h3>
<p class="text-muted">{{ post.content }}</p>
<p class="text-muted small">


+ 0
- 19
frappe/templates/pages/blog.html 파일 보기

@@ -4,25 +4,6 @@
window.category = null;
{% endblock %}

{% block style %}
<style>

.blog-post-preview {
padding: 15px 0px;
}
.blog-post-preview:last-child {
border-bottom: none;
}
.blog-post-preview h3 {
margin: 0 0 10px 0;
}
.blog-post-preview h3 a {
color: inherit !important;
text-decoration: none;
}
</style>
{% endblock %}

{% block content %}
<div class="blog-list-content">
{% if blog_introduction %}


+ 1
- 1
frappe/templates/pages/blog.py 파일 보기

@@ -46,7 +46,7 @@ def get_blog_list(start=0, by=None, category=None):

for post in posts:
post.published = global_date_format(post.creation)
post.content = re.sub('\<[/]?p\>', '', post.content[:140])
post.content = re.sub('\<[^>]*\>', '', post.content[:140])
if not post.comments:
post.comment_text = _('No comments yet')
elif post.comments==1:


+ 4
- 4
frappe/website/doctype/web_page/web_page.py 파일 보기

@@ -35,6 +35,10 @@ class WebPage(WebsiteGenerator):
if self.enable_comments:
context.comment_list = get_comment_list(self.doctype, self.name)

# for sidebar and breadcrumbs
context.children = self.get_children()
context.parents = self.get_parents(context)

if self.template_path:
# render dynamic context (if .py file exists)
context = self.get_dynamic_context(frappe._dict(context))
@@ -52,10 +56,6 @@ class WebPage(WebsiteGenerator):
# if not context.header:
# context.header = self.title

# for sidebar
if not context.children:
context.children = self.get_children()

return context

def render_dynamic(self, context):


+ 13
- 2
frappe/website/js/website.js 파일 보기

@@ -417,10 +417,19 @@ $.extend(frappe, {
var sidebar_content = $("[data-html-block='sidebar']").html(),
sidebar_has_content = sidebar_content ? !!sidebar_content.trim() : false;

// hide sidebar if no content
$(".page-sidebar, .toggle-sidebar").toggleClass("hide", !sidebar_has_content);
$(".page-sidebar").toggleClass("col-sm-push-9", sidebar_has_content);

// push sidebar to the right if there is content
$(".page-sidebar").toggleClass("col-sm-push-" + frappe.page_cols, sidebar_has_content);

// make page content wide if no sidebar
$(".page-content").toggleClass("col-sm-12", !sidebar_has_content);
$(".page-content").toggleClass("col-sm-9 col-sm-pull-3", sidebar_has_content);

// narrow page content if sidebar
$(".page-content").toggleClass("col-sm-"+frappe.page_cols+" col-sm-pull-"+frappe.sidebar_cols, sidebar_has_content);

// no borders if no sidebars
$(".page-content").toggleClass("no-border", !sidebar_has_content);

// if everything in the sub-header is hidden, hide the sub-header
@@ -582,6 +591,8 @@ $(document).ready(function() {
$(document).on("page-change", function() {
$(document).trigger("apply_permissions");
frappe.datetime.refresh_when();
frappe.sidebar_cols = $(".page-sidebar").hasClass("col-sm-3") ? 3 : 2;
frappe.page_cols = 12 - frappe.sidebar_cols;
frappe.toggle_template_blocks();
frappe.trigger_ready();
frappe.bind_filters();


+ 2
- 4
frappe/website/template.py 파일 보기

@@ -38,7 +38,8 @@ def render_blocks(context):
out["title"] = context.get("title")


if not out.get("header") and "<h1" not in out.get("content", ""):
if not out.get("header") and "<h1" not in out.get("content", "") \
and not "<!-- no-header -->" in out.get("content"):
if out.get("title"):
out["header"] = out["title"]

@@ -46,9 +47,6 @@ def render_blocks(context):
out["header"] = "<h1>" + out["header"] + "</h1>"

if "breadcrumbs" not in out:
if context.doc and hasattr(context.doc, "get_parents"):
context.parents = context.doc.get_parents(context)

out["breadcrumbs"] = scrub_relative_urls(
frappe.get_template("templates/includes/breadcrumbs.html").render(context))



불러오는 중...
취소
저장