/
disqus_export.py
133 lines (116 loc) · 5.32 KB
/
disqus_export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from optparse import make_option
import os.path
from django.conf import settings
from django.contrib import comments
from django.contrib.sites.models import Site
from django.core.management.base import NoArgsCommand
from django.utils import simplejson as json
from disqus.api import DisqusClient
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + (
make_option('-d', '--dry-run', action="store_true", dest="dry_run",
help='Does not export any comments, but merely outputs' +
'the comments which would have been exported.'),
make_option('-s', '--state-file', action="store", dest="state_file",
help="Saves the state of the export in the given file " +
"and auto-resumes from this file if possible."),
)
help = 'Export comments from contrib.comments to DISQUS'
requires_model_validation = False
def _get_comments_to_export(self, last_export_id=None):
"""Return comments which should be exported."""
qs = comments.get_model().objects.order_by('pk')\
.filter(is_public=True, is_removed=False)
if last_export_id is not None:
print "Resuming after comment %s" % str(last_export_id)
qs = qs.filter(id__gt=last_export_id)
return qs
def _get_last_state(self, state_file):
"""Checks the given path for the last exported comment's id"""
state = None
fp = open(state_file)
try:
state = int(fp.read())
print "Found previous state: %d" % (state,)
finally:
fp.close()
return state
def _save_state(self, state_file, last_pk):
"""Saves the last_pk into the given state_file"""
fp = open(state_file, 'w+')
try:
fp.write(str(last_pk))
finally:
fp.close()
def handle(self, **options):
current_site = Site.objects.get_current()
client = DisqusClient()
verbosity = int(options.get('verbosity'))
dry_run = bool(options.get('dry_run'))
state_file = options.get('state_file')
last_exported_id = None
if state_file is not None and os.path.exists(state_file):
last_exported_id = self._get_last_state(state_file)
comments = self._get_comments_to_export(last_exported_id)
comments_count = comments.count()
if verbosity >= 1:
print "Exporting %d comment(s)" % comments_count
# if this is a dry run, we output the comments and exit
if dry_run:
print comments
return
# if no comments were found we also exit
if not comments_count:
return
# Get a list of all forums for an API key. Each API key can have
# multiple forums associated. This application only supports the one
# set in the DISQUS_WEBSITE_SHORTNAME variable
forum_list = client.get_forum_list(user_api_key=settings.DISQUS_API_KEY)
try:
forum = [f for f in forum_list\
if f['shortname'] == settings.DISQUS_WEBSITE_SHORTNAME][0]
except IndexError:
raise CommandError("Could not find forum. " +
"Please check your " +
"'DISQUS_WEBSITE_SHORTNAME' setting.")
# Get the forum API key
forum_api_key = client.get_forum_api_key(
user_api_key=settings.DISQUS_API_KEY,
forum_id=forum['id'])
for comment in comments:
if verbosity >= 1:
print "Exporting comment '%s'" % comment
# Try to find a thread with the comments URL.
url = 'http://%s%s' % (
current_site.domain,
comment.content_object.get_absolute_url())
thread = client.get_thread_by_url(
url=url,
forum_api_key=forum_api_key)
# if no thread with the URL could be found, we create a new one.
# to do this, we first need to create the thread and then
# update the thread with a URL.
if not thread:
thread = client.thread_by_identifier(
forum_api_key=forum_api_key,
identifier=unicode(comment.content_object),
title=unicode(comment.content_object),
)['thread']
client.update_thread(
forum_api_key=forum_api_key,
thread_id=thread['id'],
url=url)
# name and email are optional in contrib.comments but required
# in DISQUS. If they are not set, dummy values will be used
client.create_post(
forum_api_key=forum_api_key,
thread_id=thread['id'],
message=comment.comment.encode('utf-8'),
author_name=comment.userinfo.get('name',
'nobody').encode('utf-8'),
author_email=comment.userinfo.get('email',
'nobody@example.org'),
author_url=comment.userinfo.get('url', ''),
created_at=comment.submit_date.strftime('%Y-%m-%dT%H:%M'))
if state_file is not None:
self._save_state(state_file, comment.pk)