Skip to content

Commit b5b0a8c

Browse files
committed
upgrading draceditor to martor
0 parents  commit b5b0a8c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+4552
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__pycache__
2+
build/
3+
dist/
4+
*.egg-info/
5+
*.pypirc
6+
*.pyc
7+
*backup*

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

MANIFEST.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
include LICENSE
2+
include README.md
3+
include requirements.txt
4+
recursive-include martor/templates *
5+
recursive-include martor/static *

README.rst

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
martor |pypi version|
2+
------------------------------
3+
4+
.. |pypi version|
5+
image:: https://img.shields.io/pypi/v/martor.svg?style=flat-square
6+
:target: https://pypi.python.org/pypi/martor
7+
8+
.. image:: https://img.shields.io/badge/license-GNUGPLv3-blue.svg?style=flat-square
9+
:target: https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/LICENSE
10+
11+
.. image:: https://img.shields.io/pypi/pyversions/martor.svg?style=flat-square
12+
:target: https://pypi.python.org/pypi/martor
13+
14+
.. image:: https://img.shields.io/badge/Django-1.8,%201.9,%201.10-green.svg?style=flat-square
15+
:target: https://www.djangoproject.com
16+
17+
.. image:: https://img.shields.io/pypi/dm/martor.svg?style=flat-square
18+
:target: https://pypi.python.org/pypi/martor
19+
20+
21+
**Martor** is a Django Markdown Editor and new face of **DracEditor**.
22+
23+
24+
Features
25+
------------------------------
26+
27+
* Integrated with `Ace Editor`_
28+
* Integrated with `Semantic-UI`_
29+
* Live Preview
30+
* Support Multiple Fields (`fixed this issue`_)
31+
* Upload Image to imgur.com `(via API)`
32+
* Emoji ``:emoji_name:`` + Cheat sheet
33+
* Direct Mention users ``@[username]`` - `(require user to logged in)`
34+
* Highlight ``pre``
35+
* Django Admin support
36+
* Toolbar Buttons
37+
38+
39+
Preview
40+
------------------------------
41+
42+
.. image:: https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/__screenshot/martor-preview-editor.png
43+
44+
.. image:: https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/__screenshot/martor-preview-result.png
45+
46+
47+
Requirements
48+
------------------------------
49+
50+
* ``Django>=1.10.1``
51+
* ``Markdown>=2.6.7``
52+
* ``requests>=2.12.4``
53+
54+
55+
Installation
56+
------------------------------
57+
58+
Martor is available directly from `PyPI`_:
59+
60+
1. Installing the package.
61+
62+
::
63+
64+
$ pip install martor
65+
66+
67+
2. Don't forget to add ``'martor'`` to your ``'INSTALLED_APPS'`` setting `(without migrations)`.
68+
69+
::
70+
71+
# settings.py
72+
INSTALLED_APPS = [
73+
....
74+
'martor',
75+
]
76+
77+
78+
3. Add url pattern to your ``urls.py.``
79+
80+
::
81+
82+
# urls.py
83+
urlpatterns = [
84+
...
85+
url(r'^martor/', include('martor.urls')),
86+
]
87+
88+
89+
4. Collect included some martor static files to your ``STATIC_ROOT`` folder.
90+
91+
::
92+
93+
./manage.py collectstatic
94+
95+
96+
Setting Configurations ``settings.py``
97+
---------------------------------------
98+
99+
Please register application in https://api.imgur.com/oauth2/addclient
100+
to get ``IMGUR_CLIENT_ID`` and ``IMGUR_API_KEY``.
101+
102+
::
103+
104+
# Global martor settings
105+
# Input: string boolean, `true/false`
106+
MARTOR_ENABLE_CONFIGS' = {
107+
'imgur': 'true', # to enable/disable imgur/custom uploader.
108+
'mention': 'false', # to enable/disable mention
109+
'jquery': 'true', # to include/revoke jquery (require for admin default django)
110+
}
111+
112+
# Imgur API Keys
113+
MARTOR_IMGUR_CLIENT_ID = 'your-client-id'
114+
MARTOR_IMGUR_API_KEY = 'your-api-key'
115+
116+
# Safe Mode
117+
MARTOR_MARKDOWN_SAFE_MODE = True # default
118+
119+
# Markdownify
120+
MARTOR_MARKDOWNIFY_FUNCTION = 'martor.utils.markdownify' # default
121+
MARTOR_MARKDOWNIFY_URL = '/martor/markdownify/' # default
122+
123+
# Markdown extensions (default)
124+
MARTOR_MARKDOWN_EXTENSIONS = [
125+
'markdown.extensions.extra',
126+
'markdown.extensions.nl2br',
127+
'markdown.extensions.smarty',
128+
'markdown.extensions.fenced_code',
129+
130+
# Custom markdown extensions.
131+
'martor.extensions.urlize',
132+
'martor.extensions.del_ins', # ~~strikethrough~~ and ++underscores++
133+
'martor.extensions.mention', # require for mention
134+
'martor.extensions.emoji', # require for emoji
135+
]
136+
137+
# Markdown Extensions Configs
138+
MARTOR_MARKDOWN_EXTENSION_CONFIGS = {}
139+
140+
# Markdown urls
141+
MARTOR_UPLOAD_URL = '/martor/uploader/' # default
142+
MARTOR_SEARCH_USERS_URL = '/martor/search-user/' # default
143+
144+
# Markdown Extensions
145+
MARTOR_MARKDOWN_BASE_EMOJI_URL = 'https://assets-cdn.github.com/images/icons/emoji/' # default
146+
MARTOR_MARKDOWN_BASE_MENTION_URL = 'https://python.web.id/profile/' # default (change this)
147+
148+
Check this setting is not set else csrf will not be sent over ajax calls:
149+
150+
::
151+
152+
CSRF_COOKIE_HTTPONLY = False
153+
154+
155+
Usage
156+
------------------------------
157+
158+
**Model**
159+
160+
::
161+
162+
from django.db import models
163+
from martor.models import MartorField
164+
165+
class Post(models.Model):
166+
description = MartorField()
167+
168+
169+
**Form**
170+
171+
::
172+
173+
from django import forms
174+
from martor.fields import MartorFormField
175+
176+
class PostForm(forms.Form):
177+
description = MartorFormField()
178+
179+
180+
**Admin**
181+
182+
::
183+
184+
from django.db import models
185+
from django.contrib import admin
186+
187+
from martor.widgets import AdminMartorWidget
188+
189+
from yourapp.models import YourModel
190+
191+
class YourModelAdmin(admin.ModelAdmin):
192+
formfield_overrides = {
193+
models.TextField: {'widget': AdminMartorWidget},
194+
}
195+
196+
admin.site.register(YourModel, YourModelAdmin)
197+
198+
199+
**Template**
200+
201+
Simply safe the markdown content as html ouput with loading the templatetags from ``martor/templatetags/martortags.py``.
202+
203+
::
204+
205+
{% load martortags %}
206+
{{ field_name|safe_markdown }}
207+
208+
# example
209+
{{ post.description|safe_markdown }}
210+
211+
212+
Custom Uploader
213+
-----------------
214+
215+
If you want to save the images uploaded to your storage,
216+
**Martor** also provide to handle it. Please checkout this `WIKI`_.
217+
218+
Test the Martor from this Repository
219+
-------------------------------------
220+
221+
I assume you already setup with virtual enviroment (virtualenv).
222+
223+
::
224+
225+
$ git clone https://github.com/agusmakmun/django-markdown-editor.git
226+
$ cd django-markdown-editor/ && python setup.py install
227+
$ cd martor_demo/
228+
$ python manage.py makemigrations && python manage.py migrate
229+
$ python manage.py runserver
230+
231+
232+
And let checkout at http://127.0.0.1:8000/simple-form/ to your browser.
233+
234+
235+
Martor Commands Refference
236+
--------------------------------
237+
238+
.. image:: https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/__screenshot/martor-guide.png
239+
240+
241+
Notes
242+
--------------------------------
243+
244+
**Martor** was inspired by great `django-markdownx`_, `Python Markdown`_ and `Online reStructuredText editor`_.
245+
246+
247+
.. _Ace Editor: https://ace.c9.io
248+
.. _Semantic-UI: http://semantic-ui.com
249+
.. _PyPI: https://pypi.python.org/pypi/martor
250+
.. _django-markdownx: https://github.com/adi-/django-markdownx
251+
.. _Python Markdown: https://github.com/waylan/Python-Markdown
252+
.. _Online reStructuredText editor: http://rst.ninjs.org
253+
.. _WIKI: https://github.com/agusmakmun/django-markdown-editor/wiki
254+
.. _fixed this issue: https://github.com/agusmakmun/django-markdown-editor/issues/3
56.4 KB
Loading
627 KB
Loading

foob.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
certifi==2017.7.27.1
2+
chardet==3.0.4
3+
Django==1.11.5
4+
draceditor==1.1.7
5+
idna==2.6
6+
Markdown==2.6.9
7+
pkg-resources==0.0.0
8+
pytz==2017.2
9+
requests==2.18.4
10+
urllib3==1.22

martor/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# -*- coding: utf-8 -*-
2+
3+
__VERSION__ = '1.2.0'
4+
__AUTHOR__ = 'Agus Makmun (Summon Agus)'
5+
__AUTHOR_EMAIL__ = '[email protected]'

martor/admin.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.contrib import admin
2+
from django.db import models
3+
4+
from .widgets import AdminMartorWidget
5+
from .models import MartorField
6+
7+
8+
class MartorModelAdmin(admin.ModelAdmin):
9+
10+
formfield_overrides = {
11+
MartorField: {'widget': AdminMartorWidget}
12+
}

martor/api.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
import base64
3+
import requests
4+
from .settings import (MARTOR_IMGUR_CLIENT_ID, MARTOR_IMGUR_API_KEY)
5+
6+
requests.packages.urllib3.disable_warnings()
7+
8+
9+
def imgur_uploader(image):
10+
"""
11+
Basic imgur uploader return as json data.
12+
:param `image` is from `request.FILES['markdown-image-upload']`
13+
14+
Return:
15+
success: {'status': 200, 'link': <link_image>, 'name': <image_name>}
16+
error : {'status': <error_code>, 'erorr': <erorr_message>}
17+
"""
18+
url_api = 'https://api.imgur.com/3/upload.json'
19+
headers = {'Authorization': 'Client-ID ' + MARTOR_IMGUR_CLIENT_ID}
20+
response = requests.post(
21+
url_api,
22+
headers=headers,
23+
data={
24+
'key': MARTOR_IMGUR_API_KEY,
25+
'image': base64.b64encode(image.read()),
26+
'type': 'base64',
27+
'name': image.name
28+
}
29+
)
30+
31+
"""
32+
Some function we got from `response`:
33+
34+
['connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers','history',
35+
'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json',
36+
'links', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text', 'url']
37+
"""
38+
if response.status_code == 200:
39+
respdata = json.loads(response.content.decode('utf-8'))
40+
return json.dumps({
41+
'status': respdata['status'],
42+
'link': respdata['data']['link'],
43+
'name': respdata['data']['name']
44+
})
45+
elif response.status_code == 415:
46+
# Unsupport File type
47+
return json.dumps({
48+
'status': response.status_code,
49+
'error': response.reason
50+
})
51+
return json.dumps({
52+
'status': response.status_code,
53+
'error': response.content.decode('utf-8')
54+
})

0 commit comments

Comments
 (0)