├── __init__.py
├── wp
├── __init__.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ └── import_to_blogango.py
├── templatetags
│ ├── __init__.py
│ └── wordpress_tags.py
├── views.py
├── templates
│ └── wp
│ │ ├── recent_posts.html
│ │ └── recent_comments.html
├── admin.py
├── tests.py
└── models.py
├── requirements.pip
├── .gitignore
├── .travis.yml
├── manage.py
├── setup.py
├── urls.py
├── README.md
├── LICENSE
├── settings.py
└── ez_setup.py
/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wp/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wp/management/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wp/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wp/management/commands/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wp/views.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 |
--------------------------------------------------------------------------------
/requirements.pip:
--------------------------------------------------------------------------------
1 | -e git+https://github.com/django/django.git#egg=django
2 | MySQL-python==1.2.4
3 | coverage==3.6
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.log
3 | *.temp
4 | localsettings.py
5 | *secrets.py
6 | *secret.py
7 | *.wpr
8 | *.kpf
9 | *.pydev*
10 | *.project
11 | blogango
12 | taggit
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "2.7"
4 | install:
5 | - "pip install -r requirements.pip --use-mirrors"
6 | - "pip install coveralls --use-mirrors"
7 | script: coverage run --source=wp manage.py test
8 | after_success:
9 | - coveralls
10 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/wp/templates/wp/recent_posts.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/wp/templates/wp/recent_comments.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import ez_setup
2 | ez_setup.use_setuptools()
3 | from setuptools import setup, find_packages
4 | setup(
5 | name = "django-wordpress",
6 | version = "0.2",
7 | packages = find_packages(),
8 | author = "Agiliq and friends",
9 | author_email ="shabda@agiliq.com",
10 | description = "Django app to easily integrate Wordpress.",
11 | url = "http://github.com/agiliq/django-wordpress",
12 | include_package_data = True
13 | )
14 |
--------------------------------------------------------------------------------
/wp/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from wp.models import Post, PostMeta, WpUser, UserMeta, Term, TermTaxonomy, TermRelationship
3 | from wp.models import Comment, CommentMeta, Link, Option
4 |
5 |
6 | admin.site.register(Post)
7 | admin.site.register(PostMeta)
8 | admin.site.register(WpUser)
9 | admin.site.register(UserMeta)
10 | admin.site.register(Term)
11 | admin.site.register(TermTaxonomy)
12 | admin.site.register(TermRelationship)
13 |
14 | admin.site.register(Comment)
15 | admin.site.register(CommentMeta)
16 | admin.site.register(Link)
17 | admin.site.register(Option)
--------------------------------------------------------------------------------
/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import patterns, include
2 |
3 | # Uncomment the next two lines to enable the admin:
4 | from django.contrib import admin
5 | admin.autodiscover()
6 |
7 | urlpatterns = patterns('',
8 | # Example:
9 | # (r'^wp_backport/', include('wp_backport.foo.urls')),
10 |
11 | # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
12 | # to INSTALLED_APPS to enable admin documentation:
13 | # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
14 |
15 | # Uncomment the next line to enable the admin:
16 | (r'^admin/', include(admin.site.urls)),
17 | )
18 |
--------------------------------------------------------------------------------
/wp/tests.py:
--------------------------------------------------------------------------------
1 | """
2 | This file demonstrates two different styles of tests (one doctest and one
3 | unittest). These will both pass when you run "manage.py test".
4 |
5 | Replace these with more appropriate tests for your application.
6 | """
7 |
8 | from django.test import TestCase
9 | from django.template import Template, Context
10 |
11 |
12 | class SimpleTest(TestCase):
13 | def test_template_tags(self):
14 | template_string = """
15 | {% load wordpress_tags %}
16 | {% show_comments 5 %}
17 | {% show_posts 5 %}
18 | {% populate_comments 5 as commnts%}
19 | {% populate_posts 10 as posts %}
20 | """
21 | t = Template(template_string)
22 | c = Context({})
23 | t.render(c)
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/agiliq/django-wordpress)
2 | [](https://coveralls.io/r/agiliq/django-wordpress?branch=master)
3 |
4 |
5 | This is a Django App which allows easy
6 | integration between athe Django and Wordpress.
7 |
8 | All the core Wordpress tables are made available as Django models.
9 |
10 | Installation & Usage
11 | --------------------
12 | * pip install -e git+git@github.com:agiliq/django-wordpress.git#egg=django-wordpress
13 | * Add 'wp' to installed apps.
14 | * Enter the wordpress database name in your database settings.
15 |
16 | Now, you can edit the wordpress database using django admin. And you can use templatetags for showing latest posts etc.
17 |
18 | More details are available at
19 | http://agiliq.com/blog/2010/01/wordpress-and-django-best-buddies/
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009-2013, Agiliq Solutions
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10 |
11 |
--------------------------------------------------------------------------------
/wp/templatetags/wordpress_tags.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from wp.models import Post, Comment
3 |
4 |
5 | register = template.Library()
6 |
7 |
8 | @register.inclusion_tag("wp/recent_comments.html")
9 | def show_comments(num_comments):
10 | return {"comments":Comment.objects.order_by("-comment_date")[:num_comments]}
11 |
12 |
13 | @register.inclusion_tag("wp/recent_posts.html")
14 | def show_posts(num_comments):
15 | return {"posts": Post.objects.filter(post_type="post", post_status="publish").order_by("-post_date")[:num_comments]}
16 |
17 | @register.tag
18 | def populate_comments(parser, token):
19 | "Use: {% populate_comments 5 as recent_comments %}"
20 | try:
21 | tag_name, num_comments, as_name, name = token.split_contents()
22 | except ValueError:
23 | raise template.TemplateSyntaxError("populate_comments requires three argument")
24 | return CommentsNode(num_comments, name)
25 |
26 | class CommentsNode(template.Node):
27 | def __init__(self, num_comments, name):
28 | self.num_comments = num_comments
29 | self.name = name
30 |
31 | def render(self, context):
32 | ""
33 | context[self.name] = Comment.objects.order_by("-comment_date")[:self.num_comments]
34 | return ""
35 |
36 | @register.tag
37 | def populate_posts(parser, token):
38 | "Use: {% populate_posts 5 as recent_comments %}"
39 | try:
40 | tag_name, num_posts, as_name, name = token.split_contents()
41 | except ValueError:
42 | raise template.TemplateSyntaxError("populate_posts requires three argument")
43 | return PostsNode(num_posts, name)
44 |
45 | class PostsNode(template.Node):
46 | def __init__(self, num_posts, name):
47 | self.num_posts = num_posts
48 | self.name = name
49 |
50 | def render(self, context):
51 | ""
52 | context[self.name] = Post.objects.filter(post_type="post", post_status="publish").order_by("-post_date")[:self.num_posts]
53 | return ""
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | # Django settings for wp_backport project.
2 |
3 | DEBUG = True
4 | TEMPLATE_DEBUG = DEBUG
5 |
6 | ADMINS = (
7 | # ('Your Name', 'your_email@domain.com'),
8 | )
9 |
10 | MANAGERS = ADMINS
11 |
12 |
13 | # Local time zone for this installation. Choices can be found here:
14 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
15 | # although not all choices may be available on all operating systems.
16 | # If running in a Windows environment this must be set to the same as your
17 | # system time zone.
18 | TIME_ZONE = 'America/Chicago'
19 |
20 | # Language code for this installation. All choices can be found here:
21 | # http://www.i18nguy.com/unicode/language-identifiers.html
22 | LANGUAGE_CODE = 'en-us'
23 |
24 | SITE_ID = 1
25 |
26 | # If you set this to False, Django will make some optimizations so as not
27 | # to load the internationalization machinery.
28 | USE_I18N = True
29 |
30 | # Absolute path to the directory that holds media.
31 | # Example: "/home/media/media.lawrence.com/"
32 | MEDIA_ROOT = ''
33 |
34 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a
35 | # trailing slash if there is a path component (optional in other cases).
36 | # Examples: "http://media.lawrence.com", "http://example.com/media/"
37 | MEDIA_URL = ''
38 | STATIC_URL = '/static/'
39 |
40 |
41 | # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
42 | # trailing slash.
43 | # Examples: "http://foo.com/media/", "/media/".
44 | ADMIN_MEDIA_PREFIX = '/media/'
45 |
46 | # Make this unique, and don't share it with anybody.
47 | SECRET_KEY = '@cu79xj-4n7aenosbs#v0j(bj$$0#)h457=9k+wkm7jkxi**_%'
48 |
49 | # List of callables that know how to import templates from various sources.
50 | TEMPLATE_LOADERS = (
51 | 'django.template.loaders.filesystem.Loader',
52 | 'django.template.loaders.app_directories.Loader',
53 | # 'django.template.loaders.eggs.load_template_source',
54 | )
55 |
56 | MIDDLEWARE_CLASSES = (
57 | "django.contrib.sessions.middleware.SessionMiddleware",
58 | "django.contrib.auth.middleware.AuthenticationMiddleware",
59 | "django.middleware.common.CommonMiddleware",
60 | "django.middleware.csrf.CsrfViewMiddleware",
61 | "django.contrib.messages.middleware.MessageMiddleware",
62 | )
63 |
64 | #ROOT_URLCONF = 'wp_backport.urls'
65 | ROOT_URLCONF = 'urls'
66 |
67 | TEMPLATE_DIRS = (
68 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
69 | # Always use forward slashes, even on Windows.
70 | # Don't forget to use absolute paths, not relative paths.
71 | )
72 |
73 | INSTALLED_APPS = (
74 | "django.contrib.admin",
75 | "django.contrib.auth",
76 | "django.contrib.contenttypes",
77 | "django.contrib.redirects",
78 | "django.contrib.sessions",
79 | "django.contrib.sites",
80 | "django.contrib.sitemaps",
81 | "django.contrib.staticfiles",
82 | "wp",
83 | )
84 |
85 | try:
86 | from localsettings import *
87 | except ImportError:
88 | pass
89 |
90 | DATABASES = {
91 | 'default': {
92 | 'ENGINE': 'django.db.backends.sqlite3',
93 | 'HOST': '127.0.0.1',
94 | 'NAME': 'wordpress.db',
95 | 'USER': '',
96 | 'PASSWORD': '',
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/wp/management/commands/import_to_blogango.py:
--------------------------------------------------------------------------------
1 |
2 | from django.conf import settings
3 | from django.contrib.auth.models import User
4 | from django.core.management.base import BaseCommand, CommandError
5 | from django.template.defaultfilters import slugify
6 |
7 | from wp.models import Post, Comment as WpComment, TermTaxonomy, TermRelationship, Term
8 | from blogango.models import BlogEntry, Comment, Reaction
9 |
10 | def get_auth_user(wp_author):
11 | try:
12 | auth_user = User.objects.get(username='wp_%s' % (wp_author.user_login))
13 | except User.DoesNotExist:
14 | auth_user = User.objects.create_user(username='wp_%s' % (wp_author.user_login),
15 | email = wp_author.user_email)
16 | auth_user.first_name = wp_author.user_nicename
17 | auth_user.save()
18 | return auth_user
19 |
20 | COMMENT_AGENTS = ['btc_reddit', 'btc_yc', 'btc_twitter', 'btc_friendfeed', 'btc_blog']
21 | class Command(BaseCommand):
22 | help = 'Import blog posts from wordpress to blogango'
23 | def handle(self, *args, **kwargs):
24 | if 'blogango' not in settings.INSTALLED_APPS:
25 | raise CommandError('Add blogango to installed apps to import posts from wordpress')
26 |
27 | # get the offset id from blogango
28 | blog_entries = BlogEntry.objects.all().order_by('-id')
29 | offset = blog_entries.count() and blog_entries[0].id or 0
30 | wp_posts = Post.objects.filter(id__gt=offset, post_status='publish', post_type='post')
31 |
32 | for wp_post in wp_posts:
33 | # insert into BlogEntry
34 | print wp_post.post_date
35 |
36 | blog_entry = BlogEntry.objects.create(id=wp_post.id,
37 | title=wp_post.post_title,
38 | slug=slugify(wp_post.post_title),
39 | text=wp_post.post_content,
40 | created_by=get_auth_user(wp_post.post_author))
41 | blog_entry.created_on = wp_post.post_date
42 | blog_entry.save()
43 |
44 | tables = ['wp_term_taxonomy', 'wp_term_relationships']
45 | where = ['wp_term_relationships.object_id = %s',
46 | 'wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id',
47 | 'wp_term_taxonomy.term_id = wp_terms.term_id',
48 | 'wp_term_taxonomy.taxonomy = %s']
49 |
50 | # get categories
51 | categories = Term.objects.extra(tables=tables, where=where, params=[wp_post.id, 'category'])
52 | for category in categories:blog_entry.tags.add(category.name)
53 |
54 | # get tags
55 | # tags = Term.objects.extra(tables=tables, where=where, params=[wp_post.id, 'post_tag'])
56 | # for tag in tags:blog_entry.tags.add(tag.name)
57 |
58 | # add comments
59 | wp_comments = WpComment.objects.filter(comment_post_id=wp_post.id, comment_approved=1)
60 | for wp_comment in wp_comments:
61 | if wp_comment.comment_type == 'pingback':continue
62 | if wp_comment.comment_agent in COMMENT_AGENTS:
63 | comment = Reaction.objects.create(text=wp_comment.comment_content,
64 | comment_for=blog_entry,
65 | user_name=wp_comment.comment_author,
66 | user_url=wp_comment.comment_author_url,
67 | source=wp_comment.comment_agent.lstrip('btc_'))
68 | else:
69 | comment = Comment.objects.create(text=wp_comment.comment_content,
70 | comment_for=blog_entry,
71 | user_name=wp_comment.comment_author,
72 | user_url=wp_comment.comment_author_url,
73 | email_id=wp_comment.comment_author_email)
74 | comment.created_on = wp_comment.comment_date
75 | comment.is_public = True
76 | comment.save()
77 |
--------------------------------------------------------------------------------
/wp/models.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.db import models
4 |
5 |
6 | class WpUser(models.Model):
7 | """This has been given a wp prefix, as contrib.user is so commonly
8 | imported name, and we do not want to namespace this everywhere."""
9 |
10 | id = models.BigIntegerField(db_column='ID', primary_key=True) # Field name made lowercase.
11 | user_login = models.CharField(max_length=60)
12 | user_pass = models.CharField(max_length=64)
13 | user_nicename = models.CharField(max_length=50)
14 | user_email = models.CharField(max_length=100)
15 | user_url = models.CharField(max_length=100)
16 | user_registered = models.DateTimeField()
17 | user_activation_key = models.CharField(max_length=60)
18 | user_status = models.IntegerField()
19 | display_name = models.CharField(max_length=250)
20 |
21 | class Meta:
22 | verbose_name = u'User'
23 | verbose_name_plural = u'Users'
24 | db_table = 'wp_users'
25 |
26 | def __unicode__(self):
27 | return self.user_nicename
28 |
29 | class Link(models.Model):
30 | link_id = models.BigIntegerField(primary_key=True)
31 | link_url = models.CharField(max_length=255)
32 | link_name = models.CharField(max_length=255)
33 | link_image = models.CharField(max_length=255)
34 | link_target = models.CharField(max_length=25)
35 | link_description = models.CharField(max_length=255)
36 | link_visible = models.CharField(max_length=20)
37 | link_owner = models.ForeignKey(WpUser, db_column='link_owner')
38 | link_rating = models.IntegerField()
39 | link_updated = models.DateTimeField()
40 | link_rel = models.CharField(max_length=255)
41 | link_notes = models.TextField()
42 | link_rss = models.CharField(max_length=255)
43 |
44 | class Meta:
45 | verbose_name = u'Link'
46 | verbose_name_plural = u'Link'
47 | db_table = u'wp_links'
48 |
49 | def __unicode__(self):
50 | return self.link_name
51 |
52 | class Option(models.Model):
53 | option_id = models.BigIntegerField(primary_key=True)
54 | option_name = models.CharField(unique=True, max_length=64)
55 | option_value = models.TextField()
56 | autoload = models.CharField(max_length=20)
57 |
58 | class Meta:
59 | verbose_name = u'Option'
60 | verbose_name_plural = u'Options'
61 | db_table = u'wp_options'
62 |
63 | def __unicode__(self):
64 | return self.option_name
65 |
66 | class Post(models.Model):
67 | id = models.BigIntegerField(db_column='ID', primary_key=True) # Field name made lowercase.
68 | post_author = models.ForeignKey(WpUser, db_column='post_author')
69 | post_parent = models.ForeignKey('self', db_column='post_parent')
70 | post_date = models.DateTimeField()
71 | post_date_gmt = models.DateTimeField()
72 | post_content = models.TextField()
73 | post_title = models.TextField()
74 | post_excerpt = models.TextField()
75 | post_status = models.CharField(max_length=20)
76 | comment_status = models.CharField(max_length=20)
77 | ping_status = models.CharField(max_length=20)
78 | post_password = models.CharField(max_length=20)
79 | post_name = models.CharField(max_length=200)
80 | to_ping = models.TextField()
81 | pinged = models.TextField()
82 | post_modified = models.DateTimeField()
83 | post_modified_gmt = models.DateTimeField()
84 | post_content_filtered = models.TextField()
85 |
86 | guid = models.CharField(max_length=255)
87 | menu_order = models.IntegerField()
88 | post_type = models.CharField(max_length=20)
89 | post_mime_type = models.CharField(max_length=100)
90 | comment_count = models.BigIntegerField()
91 |
92 | class Meta:
93 | verbose_name = u'Post'
94 | verbose_name_plural = u'Posts'
95 | db_table = u'wp_posts'
96 |
97 | def __unicode__(self):
98 | return self.post_title or str(self.id)
99 |
100 | def get_absolute_url(self):
101 | return self.guid
102 |
103 | class PostMeta(models.Model):
104 | meta_id = models.BigIntegerField(primary_key=True)
105 | post = models.ForeignKey(Post)
106 | meta_key = models.CharField(max_length=255, blank=True)
107 | meta_value = models.TextField(blank=True)
108 |
109 | class Meta:
110 | verbose_name = u'Post Meta'
111 | verbose_name_plural = u'Posts Meta'
112 | db_table = u'wp_postmeta'
113 |
114 | def __unicode__(self):
115 | return self.post.post_title or str(self.post.id)
116 |
117 | class Comment(models.Model):
118 | comment_id = models.BigIntegerField(db_column='comment_ID', primary_key=True) # Field name made lowercase.
119 | comment_post_id = models.ForeignKey(Post, db_column='comment_post_ID') # Field name made lowercase.
120 | comment_author = models.TextField()
121 | comment_author_email = models.CharField(max_length=100)
122 | comment_author_url = models.CharField(max_length=200)
123 | comment_author_ip = models.CharField(db_column='comment_author_IP', max_length=100) # Field name made lowercase.
124 | comment_date = models.DateTimeField()
125 | comment_date_gmt = models.DateTimeField()
126 | comment_content = models.TextField()
127 | comment_karma = models.IntegerField()
128 | comment_approved = models.CharField(max_length=20)
129 | comment_agent = models.CharField(max_length=255)
130 | comment_type = models.CharField(max_length=20)
131 | comment_parent = models.BigIntegerField()
132 | user_id = models.BigIntegerField()
133 |
134 | class Meta:
135 | verbose_name = u'Comment'
136 | verbose_name_plural = u'Comments'
137 | db_table = u'wp_comments'
138 |
139 | def __unicode__(self):
140 | return self.comment_content[:50]
141 |
142 |
143 | class CommentMeta(models.Model):
144 | meta_id = models.BigIntegerField(primary_key=True)
145 | comment_id = models.BigIntegerField()
146 | meta_key = models.CharField(max_length=255, blank=True)
147 | meta_value = models.TextField(blank=True)
148 |
149 | class Meta:
150 | verbose_name = u'Comment Meta'
151 | verbose_name_plural = u'Comments Meta'
152 | db_table = u'wp_commentmeta'
153 |
154 | def __unicode__(self):
155 | return self.meta_key
156 |
157 | class Term(models.Model):
158 | term_id = models.BigIntegerField(primary_key=True)
159 | name = models.CharField(max_length=200)
160 | slug = models.CharField(unique=True, max_length=200)
161 | term_group = models.BigIntegerField()
162 |
163 | class Meta:
164 | verbose_name = u'Term'
165 | verbose_name_plural = u'Terms'
166 | db_table = u'wp_terms'
167 |
168 | def __unicode__(self):
169 | return self.name
170 |
171 | class TermTaxonomy(models.Model):
172 | term_taxonomy_id = models.BigIntegerField(primary_key=True)
173 | term = models.ForeignKey(Term, unique=True)
174 | taxonomy = models.CharField(max_length=32)
175 | description = models.TextField()
176 | parent = models.BigIntegerField()
177 | count = models.BigIntegerField()
178 |
179 | class Meta:
180 | verbose_name = "Term Taxonomy"
181 | verbose_name_plural = "Term Taxonomies"
182 | db_table = u'wp_term_taxonomy'
183 |
184 | def __unicode__(self):
185 | return self.taxonomy
186 |
187 |
188 | class TermRelationship(models.Model):
189 | object_id = models.BigIntegerField(primary_key=True)
190 | term_taxonomy = models.ForeignKey(TermTaxonomy)
191 | term_order = models.IntegerField()
192 |
193 | class Meta:
194 | verbose_name = u'Term Relationship'
195 | verbose_name_plural = u'Term Relationships'
196 | db_table = u'wp_term_relationships'
197 |
198 | class UserMeta(models.Model):
199 | umeta_id = models.BigIntegerField(primary_key=True)
200 | user = models.ForeignKey(WpUser)
201 | meta_key = models.CharField(max_length=255, blank=True)
202 | meta_value = models.TextField(blank=True)
203 |
204 | class Meta:
205 | verbose_name = 'User Meta'
206 | verbose_name_plural = 'Users Meta'
207 | db_table = u'wp_usermeta'
208 |
209 | def __unicode__(self):
210 | return self.user.user_nicename
211 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/ez_setup.py:
--------------------------------------------------------------------------------
1 | #!python
2 | """Bootstrap setuptools installation
3 |
4 | If you want to use setuptools in your package's setup.py, just include this
5 | file in the same directory with it, and add this to the top of your setup.py::
6 |
7 | from ez_setup import use_setuptools
8 | use_setuptools()
9 |
10 | If you want to require a specific version of setuptools, set a download
11 | mirror, or use an alternate download directory, you can do so by supplying
12 | the appropriate options to ``use_setuptools()``.
13 |
14 | This file can also be run as a script to install or upgrade setuptools.
15 | """
16 | import sys
17 | DEFAULT_VERSION = "0.6c11"
18 | DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
19 |
20 | md5_data = {
21 | 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
22 | 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
23 | 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
24 | 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
25 | 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
26 | 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
27 | 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
28 | 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
29 | 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
30 | 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
31 | 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
32 | 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
33 | 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
34 | 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
35 | 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
36 | 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
37 | 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
38 | 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
39 | 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
40 | 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
41 | 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
42 | 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
43 | 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
44 | 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
45 | 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
46 | 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
47 | 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
48 | 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
49 | 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
50 | 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
51 | 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
52 | 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
53 | 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
54 | 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
55 | 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
56 | 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
57 | 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
58 | 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
59 | 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
60 | 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
61 | 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
62 | 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
63 | }
64 |
65 | import sys, os
66 | try: from hashlib import md5
67 | except ImportError: from md5 import md5
68 |
69 | def _validate_md5(egg_name, data):
70 | if egg_name in md5_data:
71 | digest = md5(data).hexdigest()
72 | if digest != md5_data[egg_name]:
73 | print >>sys.stderr, (
74 | "md5 validation of %s failed! (Possible download problem?)"
75 | % egg_name
76 | )
77 | sys.exit(2)
78 | return data
79 |
80 | def use_setuptools(
81 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
82 | download_delay=15
83 | ):
84 | """Automatically find/download setuptools and make it available on sys.path
85 |
86 | `version` should be a valid setuptools version number that is available
87 | as an egg for download under the `download_base` URL (which should end with
88 | a '/'). `to_dir` is the directory where setuptools will be downloaded, if
89 | it is not already available. If `download_delay` is specified, it should
90 | be the number of seconds that will be paused before initiating a download,
91 | should one be required. If an older version of setuptools is installed,
92 | this routine will print a message to ``sys.stderr`` and raise SystemExit in
93 | an attempt to abort the calling script.
94 | """
95 | was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
96 | def do_download():
97 | egg = download_setuptools(version, download_base, to_dir, download_delay)
98 | sys.path.insert(0, egg)
99 | import setuptools; setuptools.bootstrap_install_from = egg
100 | try:
101 | import pkg_resources
102 | except ImportError:
103 | return do_download()
104 | try:
105 | pkg_resources.require("setuptools>="+version); return
106 | except pkg_resources.VersionConflict, e:
107 | if was_imported:
108 | print >>sys.stderr, (
109 | "The required version of setuptools (>=%s) is not available, and\n"
110 | "can't be installed while this script is running. Please install\n"
111 | " a more recent version first, using 'easy_install -U setuptools'."
112 | "\n\n(Currently using %r)"
113 | ) % (version, e.args[0])
114 | sys.exit(2)
115 | else:
116 | del pkg_resources, sys.modules['pkg_resources'] # reload ok
117 | return do_download()
118 | except pkg_resources.DistributionNotFound:
119 | return do_download()
120 |
121 | def download_setuptools(
122 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
123 | delay = 15
124 | ):
125 | """Download setuptools from a specified location and return its filename
126 |
127 | `version` should be a valid setuptools version number that is available
128 | as an egg for download under the `download_base` URL (which should end
129 | with a '/'). `to_dir` is the directory where the egg will be downloaded.
130 | `delay` is the number of seconds to pause before an actual download attempt.
131 | """
132 | import urllib2, shutil
133 | egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
134 | url = download_base + egg_name
135 | saveto = os.path.join(to_dir, egg_name)
136 | src = dst = None
137 | if not os.path.exists(saveto): # Avoid repeated downloads
138 | try:
139 | from distutils import log
140 | if delay:
141 | log.warn("""
142 | ---------------------------------------------------------------------------
143 | This script requires setuptools version %s to run (even to display
144 | help). I will attempt to download it for you (from
145 | %s), but
146 | you may need to enable firewall access for this script first.
147 | I will start the download in %d seconds.
148 |
149 | (Note: if this machine does not have network access, please obtain the file
150 |
151 | %s
152 |
153 | and place it in this directory before rerunning this script.)
154 | ---------------------------------------------------------------------------""",
155 | version, download_base, delay, url
156 | ); from time import sleep; sleep(delay)
157 | log.warn("Downloading %s", url)
158 | src = urllib2.urlopen(url)
159 | # Read/write all in one block, so we don't create a corrupt file
160 | # if the download is interrupted.
161 | data = _validate_md5(egg_name, src.read())
162 | dst = open(saveto,"wb"); dst.write(data)
163 | finally:
164 | if src: src.close()
165 | if dst: dst.close()
166 | return os.path.realpath(saveto)
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 | def main(argv, version=DEFAULT_VERSION):
204 | """Install or upgrade setuptools and EasyInstall"""
205 | try:
206 | import setuptools
207 | except ImportError:
208 | egg = None
209 | try:
210 | egg = download_setuptools(version, delay=0)
211 | sys.path.insert(0,egg)
212 | from setuptools.command.easy_install import main
213 | return main(list(argv)+[egg]) # we're done here
214 | finally:
215 | if egg and os.path.exists(egg):
216 | os.unlink(egg)
217 | else:
218 | if setuptools.__version__ == '0.0.1':
219 | print >>sys.stderr, (
220 | "You have an obsolete version of setuptools installed. Please\n"
221 | "remove it from your system entirely before rerunning this script."
222 | )
223 | sys.exit(2)
224 |
225 | req = "setuptools>="+version
226 | import pkg_resources
227 | try:
228 | pkg_resources.require(req)
229 | except pkg_resources.VersionConflict:
230 | try:
231 | from setuptools.command.easy_install import main
232 | except ImportError:
233 | from easy_install import main
234 | main(list(argv)+[download_setuptools(delay=0)])
235 | sys.exit(0) # try to force an exit
236 | else:
237 | if argv:
238 | from setuptools.command.easy_install import main
239 | main(argv)
240 | else:
241 | print "Setuptools version",version,"or greater has been installed."
242 | print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
243 |
244 | def update_md5(filenames):
245 | """Update our built-in md5 registry"""
246 |
247 | import re
248 |
249 | for name in filenames:
250 | base = os.path.basename(name)
251 | f = open(name,'rb')
252 | md5_data[base] = md5(f.read()).hexdigest()
253 | f.close()
254 |
255 | data = [" %r: %r,\n" % it for it in md5_data.items()]
256 | data.sort()
257 | repl = "".join(data)
258 |
259 | import inspect
260 | srcfile = inspect.getsourcefile(sys.modules[__name__])
261 | f = open(srcfile, 'rb'); src = f.read(); f.close()
262 |
263 | match = re.search("\nmd5_data = {\n([^}]+)}", src)
264 | if not match:
265 | print >>sys.stderr, "Internal error!"
266 | sys.exit(2)
267 |
268 | src = src[:match.start(1)] + repl + src[match.end(1):]
269 | f = open(srcfile,'w')
270 | f.write(src)
271 | f.close()
272 |
273 |
274 | if __name__=='__main__':
275 | if len(sys.argv)>2 and sys.argv[1]=='--md5update':
276 | update_md5(sys.argv[2:])
277 | else:
278 | main(sys.argv[1:])
279 |
280 |
281 |
282 |
283 |
284 |
285 |
--------------------------------------------------------------------------------