Commit a45cdf15a03943b70ca7fc9675a00811ef4f707a

cil-b17f8ceb: Added ability to import nodes along with comments
admin.py
(5 / 0)
  
2020import comment
2121
2222sys.path.append('node')
23sys.path.append('admin')
2324import recipe
25import load
2426
2527import migrate
2628
7878 # comments
7979 ('/admin/comment/', comment.Index),
8080 ('/admin/comment/del.html', comment.Del),
81
82 # load
83 ('/admin/load/', load.Import),
8184
8285 # migrations
8386 ('/admin/migrate/', migrate.Migrate),
admin/load.py
(127 / 0)
  
1## ----------------------------------------------------------------------------
2# import standard modules
3import re
4import logging
5import sys
6import yaml
7import datetime
8
9# Google specific modules
10from google.appengine.ext import db
11from google.appengine.api.labs.taskqueue import Task
12from google.appengine.api.datastore_errors import BadKeyError
13from django.utils import simplejson
14
15# local modules
16sys.path.append("..")
17from models import Section, Page, Recipe, Comment
18import models
19import webbase
20import formbase
21import util
22
23## ----------------------------------------------------------------------------
24
25class Import(webbase.WebBase):
26 def get(self):
27 vals = {
28 'sections' : Section.all(),
29 'node_types' : models.node_choices,
30 'title' : 'Import a node',
31 'data_types' : [
32 { 'value' : 'json', 'text' : 'JSON' },
33 { 'value' : 'yaml', 'text' : 'YAML' },
34 ],
35 }
36 self.template( 'load-form.html', vals, 'admin' );
37
38 def post(self):
39 msgs = []
40 section = None
41 try:
42 section = Section.get( self.request.get('section') )
43 except BadKeyError:
44 # invalid key, try again
45 self.redirect('.')
46
47 node_type = self.request.get('node_type')
48 data_input = self.request.get('data_input')
49 data_type = self.request.get('data_type')
50 data = None
51 if data_type == 'json':
52 logging.info(data_input)
53 data = simplejson.loads( data_input )
54 elif data_type == 'yaml':
55 data = yaml.load( data_input )
56 else:
57 # someone is messing with the input params
58 self.redirect('.')
59
60 logging.info(data)
61
62 # figure out what this node_type is
63 item = None
64 if node_type == 'page':
65 item = Page(
66 section = Section.get( self.request.get('section') ),
67 name = data['name'],
68 title = data['title'],
69 content = data['content'],
70 type = data['type'],
71 label_raw = ' '.join( data['label'] ),
72 attribute_raw = ' '.join( data['attribute'] ),
73 inserted = util.str_to_datetime( data['inserted'] ),
74 updated = util.str_to_datetime( data['updated'] ),
75 )
76 logging.info('here1')
77
78 elif node_type == 'recipe':
79 item = Recipe(
80 section = Section.get( self.request.get('section') ),
81 name = data['name'],
82 title = data['title'],
83 intro = data['intro'],
84 serves = data['serves'],
85 ingredients = data['ingredients'],
86 method = data['method'],
87 type = data['type'],
88 label_raw = ' '.join( data['label'] ),
89 attribute_raw = ' '.join( data['attribute'] ),
90 inserted = util.str_to_datetime( data['inserted'] ),
91 updated = util.str_to_datetime( data['updated'] ),
92 )
93 logging.info('here2')
94
95 else:
96 # again, someone is messing with the input params
97 self.redirect('.')
98
99 # regenerate this item
100 item.set_derivatives()
101 item.put()
102 item.section.regenerate()
103
104 msgs.append( 'Added node [%s, %s]' % (item.name, item.title) )
105
106 if 'comments' in data:
107 for comment in data['comments']:
108 # load each comment in against this node
109 comment = Comment(
110 node = item,
111 name = comment['name'],
112 email = comment['email'],
113 website = comment['website'],
114 comment = comment['comment'],
115 comment_html = util.render(comment['comment'], 'text'),
116 inserted = util.str_to_datetime( comment['inserted'] ),
117 updated = util.str_to_datetime( comment['updated'] ),
118 )
119 comment.put()
120 msgs.append( 'Added comment [%s, %s]' % (comment.name, comment.email) )
121
122 # now that we've added some comments, make the node regenerate
123 item.regenerate()
124
125 self.template( 'load-import.html', { 'msgs' : msgs }, 'admin' );
126
127## ----------------------------------------------------------------------------
  
1Issue: b17f8ceb
2CreatedBy: Andrew Chilton <andychilton@gmail.com>
3Inserted: 2009-12-23T05:48:48
4Updated: 2009-12-23T07:05:42
5
6Also going to add the ability to load in JSON (as well as YAML).
  
11Summary: Add an import page so we can manually do old entries
2Status: InProgress
2Status: Finished
33CreatedBy: Andrew Chilton <andychilton@gmail.com>
44AssignedTo: Andrew Chilton <andychilton@gmail.com>
55Label: Milestone-v0.04
6Comment: 6cb461af
67Inserted: 2009-12-22T10:07:57
7Updated: 2009-12-22T10:13:51
8Updated: 2009-12-23T08:43:11
89
910After playing with the remote_api and it being just terrible, and also looking
1011at the bulk loader and it being overly complicated, I've decided to just have a
models.py
(1 / 0)
  
2121# * updated = db.DateTimeProperty( auto_now = True )
2222
2323type_choices = ["text", "code", "phliky", "textile", "html", "markdown"]
24node_choices = ['page', 'recipe']
2425layout_choices = ['content', 'blog', 'faq']
2526
2627## ----------------------------------------------------------------------------
  
1{% extends "wrapper.html" %}
2
3{% block content %}
4
5<h2>Import a Node (with Comments)</h2>
6
7<form method="post" action="">
8
9 <table class="edit">
10 <tbody>
11
12 <tr>
13 <th><label for="id_section">Section:</label></th>
14 <td>
15 <select id="id_section" name="section">
16 <option value="">Select...</option>
17 {% for section in sections %}
18 <option value="{{ section.key|urlencode }}"{% ifequal section.key item.section.key %} selected="selected"{% endifequal %}>{{ section.path|escape }}</option>
19 {% endfor %}
20 </select>
21 </td>
22 </tr>
23
24 <tr>
25 <th><label for="id_node_type">Node Type:</label></th>
26 <td>
27 <select id="id_node_type" name="node_type">
28 <option value="">Select...</option>
29 {% for node_type in node_types %}
30 <option value="{{ node_type|escape }}">{{ node_type|escape }}</option>
31 {% endfor %}
32 </select>
33 </td>
34 </tr>
35
36 <tr>
37 <th><label for="id_data">Data:</label></th>
38 <td><textarea id="id_data" name="data_input" class="large"></textarea></td>
39 </tr>
40
41 <tr>
42 <th><label for="id_data_type">Data Type:</label></th>
43 <td>
44 {% for data_type in data_types %}
45 <input type="radio" id="id_data_type" name="data_type" value="{{ data_type.value|escape }}"{% if forloop.first %} checked="checked"{% endif %} /> {{ data_type.text|escape }}
46 {% if not forloop.last %}<br />{% endif %}
47 {% endfor %}
48 </td>
49 </tr>
50
51 </tbody>
52 </table>
53
54 <input type="submit"/>
55
56</form>
57
58{% endblock %}
  
1{% extends "wrapper.html" %}
2
3{% block content %}
4
5<h2>Node Imported</h2>
6
7<ul>
8{% for msg in msgs %}
9 <li>{{ msg|escape }}</li>
10{% endfor %}
11</ul>
12
13<p><a href=".">Import Another</a></p>
14
15{% endblock %}
  
2626 <select id="id_section" name="section">
2727 <option value="">Select...</option>
2828{% for section in sections %}
29 <option value="{{ section.key|urlencode }}"{% ifequal section.key item.section.key %} selected="selected"{% endifequal %}>{{ section.path|escape }}</option>
29 <option value="{{ section.key|escape }}"{% ifequal section.key item.section.key %} selected="selected"{% endifequal %}>{{ section.path|escape }}</option>
3030{% endfor %}
3131 </select>
3232 </td>
4444
4545 <tr>
4646 <th><label for="id_content">Content:</label></th>
47 <td><textarea id="id_content" name="content" class="content">{{ item.content|escape }}</textarea></td>
47 <td><textarea id="id_content" name="content" class="medium">{{ item.content|escape }}</textarea></td>
4848 </tr>
4949
5050 <tr>
  
5050 <li>
5151 <a href="/admin/recipe/">Recipe</a> (<a href="/admin/recipe/new.html">New</a>)
5252 </li>
53 <li>
54 <a href="/admin/load/">Import</a>
55 </li>
5356 </ul>
5457 </li>
5558 <li>
util.py
(8 / 0)
  
77import sys
88import cgi
99import re
10import datetime
11import re
1012
1113## ----------------------------------------------------------------------------
1214# local modules
7878 name = re.sub(r'-$', '', name )
7979
8080 return name
81
82def str_to_datetime(str):
83 """ takes strings of the form yyyy-mm-dd hh:mm:ss and returns a datetime """
84 a = [ int(x) for x in re.split(r'[ \-:]', str) ]
85 dt = datetime.datetime(a[0], a[1], a[2], a[3], a[4], a[5])
86 return dt
8187
8288## ----------------------------------------------------------------------------