root/trunk/pylucid_project/PyLucid/plugins_internal/find_and_replace/find_and_replace.py

Revision 1719, 4.5 KB (checked in by JensDiemer, 20 months ago)

change "from django import newforms as forms" to "from django import forms":  http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges#Movednewformstoforms

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Rev LastChangedDate
Line 
1# -*- coding: utf-8 -*-
2
3"""
4    PyLucid find and replace
5    ~~~~~~~~~~~~~~~~~~~~~~~~
6
7    Find/Replace in all page/template/stylesheet content.
8
9    Known bugs:
10        SQLite doesn’t support case-sensitive LIKE statements, we add some
11        "SQLite work-a-round" for this. Otherwise we would get a empty result
12        list. Note: The real replace operation always works case-sensitive.
13        See also: http://www.djangoproject.com/documentation/db-api/#contains
14
15    Last commit info:
16    ~~~~~~~~~
17    $LastChangedDate$
18    $Rev$
19    $Author$
20
21    :copyleft: 2008 by the PyLucid team, see AUTHORS for more details.
22    :license: GNU GPL v2 or above, see LICENSE for more details
23"""
24
25__version__= "$Rev$"
26
27import time
28
29from django import forms
30from django.utils.safestring import mark_safe
31from django.utils.translation import ugettext as _
32
33from PyLucid.system.BasePlugin import PyLucidBasePlugin
34from PyLucid.models import Page, Plugin, Template, Style
35from PyLucid.tools.Diff import diff_lines
36from PyLucid.tools.utils import escape
37
38
39# for FindReplaceForm ChoiceField
40TYPES = (
41    ("pages", "pages"),
42    ("templates", "templates"),
43    ("stylesheets", "stylesheets"),
44)
45
46
47# We used preferences values in a newform. We need these values here.
48preferences = Plugin.objects.get_preferences(__file__)
49
50min_term_len = preferences["min_term_len"]
51max_term_len = preferences["max_term_len"]
52
53
54class FindReplaceForm(forms.Form):
55    # TODO: min und max should be saved in the prefereces.
56    find_string = forms.CharField(
57        min_length = min_term_len, max_length = max_term_len,
58    )
59    replace_string = forms.CharField(
60        min_length = min_term_len, max_length = max_term_len,
61    )
62    type = forms.ChoiceField(
63        choices=TYPES,
64        help_text = _("Please select the content type for the operation.")
65    )
66    simulate = forms.BooleanField(
67        initial = True, required = False,
68        help_text = _("Don't replace anything.")
69
70    )
71
72
73class find_and_replace(PyLucidBasePlugin):
74
75    def find_and_replace(self):
76        context = {}
77        if self.request.method == 'POST':
78            form = FindReplaceForm(self.request.POST)
79            if form.is_valid():
80                start_time = time.time()
81                results, total_changes = self.do(**form.cleaned_data)
82                context = {
83                    "results": results,
84                    "total_changes": total_changes,
85                    "duration": time.time() - start_time,
86                }
87        else:
88            form = FindReplaceForm()
89
90        context["form"] = form
91        self._render_template("find_and_replace", context)#, debug=True)
92
93
94    def do(self, find_string, replace_string, type, simulate):
95        """
96        Do the find/replace action.
97        Returns a result list with diff information.
98        """
99        def nothing_found():
100            # We used this two times
101            self.page_msg(
102                "No %s contains the string '%s'" % (type, find_string)
103            )
104            return None, None
105
106        if type == "pages":
107            model_object = Page
108        elif type == "templates":
109            model_object = Template
110        elif type == "stylesheets":
111            model_object = Style
112        else:
113            self.page_msg.red("Wrong type!")
114            return None, None
115
116        items = model_object.objects.all().filter(
117            content__contains=find_string
118        )
119        if len(items) == 0:
120            return nothing_found()
121
122        total_changes = 0
123        results = []
124        changed_items = []
125        for item in items:
126            old_content = item.content
127
128            changes = old_content.count(find_string)
129            if changes == 0:
130                # SQlite work-a-round for the
131                continue
132
133            total_changes += changes
134
135            new_content = old_content.replace(find_string, replace_string)
136            if not simulate:
137                # Save the find/replace result
138                item.content = new_content
139                item.save()
140                changed_items.append(item.name)
141
142            diff = diff_lines(old_content, new_content)
143            diff = escape(diff)
144            diff = mark_safe(diff)
145
146            results.append({
147                "item": item,
148                "changes": changes,
149                "diff": diff,
150            })
151
152        if total_changes == 0:
153            # SQLite work-a-round
154            return nothing_found()
155
156        if not simulate:
157            self.page_msg.green("Changed %s:" % type)
158            self.page_msg.green(", ".join(changed_items))
159
160        return results, total_changes
161
162
163
Note: See TracBrowser for help on using the browser.