Merged [4999] from jmh@joelhalpern.com:

Correct test of final shepherd update flag.
 - Legacy-Id: 5014
Note: SVN reference [4999] has been migrated to Git commit aba18e8f38364ad17d451d0ed7e33aa01dfbeb52
This commit is contained in:
Henrik Levkowetz 2012-11-07 12:50:38 +00:00
commit 3a7480520f
11 changed files with 351 additions and 187 deletions

View file

@ -5,11 +5,13 @@ try:
import syslog
write = syslog.syslog
except ImportError: # import syslog will fail on Windows boxes
pass
import sys
write = lambda x: sys.stderr.write(x+"\n")
from pprint import pformat
import sys
write = lambda x: sys.stderr.write(x+"\n")
try:
from pprint import pformat
except ImportError:
pformat = lambda x: x
import cProfile
try:
from django.conf import settings

View file

@ -519,14 +519,6 @@ class BallotWriteupForm(forms.ModelForm):
def clean_ballot_writeup(self):
return self.cleaned_data["ballot_writeup"].replace("\r", "")
class ApprovalTextForm(forms.ModelForm):
class Meta:
model = BallotInfo
fields = ["approval_text"]
def clean_approval_text(self):
return self.cleaned_data["approval_text"].replace("\r", "")
@group_required('Area_Director','Secretariat')
def lastcalltext(request, name):
"""Editing of the last call text"""
@ -848,64 +840,15 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
ballot_writeupnotes = ballot_writeupnotesREDESIGN
@group_required('Area_Director','Secretariat')
def ballot_approvaltext(request, name):
"""Editing of approval text"""
doc = get_object_or_404(InternetDraft, filename=name)
if not doc.idinternal:
raise Http404()
login = IESGLogin.objects.get(login_name=request.user.username)
try:
ballot = doc.idinternal.ballot
except BallotInfo.DoesNotExist:
ballot = generate_ballot(request, doc)
approval_text_form = ApprovalTextForm(instance=ballot)
if request.method == 'POST':
if "save_approval_text" in request.POST:
approval_text_form = ApprovalTextForm(request.POST, instance=ballot)
if approval_text_form.is_valid():
ballot.approval_text = approval_text_form.cleaned_data["approval_text"]
add_document_comment(request, doc, "Approval announcement text changed")
ballot.save()
if "regenerate_approval_text" in request.POST:
ballot.approval_text = generate_approval_mail(request, doc)
add_document_comment(request, doc, "Approval announcement text regenerated")
ballot.save()
# make sure form has the updated text
approval_text_form = ApprovalTextForm(instance=ballot)
doc.idinternal.event_date = date.today()
doc.idinternal.save()
can_announce = doc.idinternal.cur_state_id > 19
docs_with_invalid_status = [d.document().file_tag() for d in doc.idinternal.ballot_set() if "None" in d.document().intended_status.intended_status or "Request" in d.document().intended_status.intended_status]
need_intended_status = ", ".join(docs_with_invalid_status)
return render_to_response('idrfc/ballot_approvaltext.html',
dict(doc=doc,
back_url=doc.idinternal.get_absolute_url(),
ballot=ballot,
approval_text_form=approval_text_form,
can_announce=can_announce,
need_intended_status=need_intended_status,
),
context_instance=RequestContext(request))
class ApprovalTextFormREDESIGN(forms.Form):
class ApprovalTextForm(forms.Form):
approval_text = forms.CharField(widget=forms.Textarea, required=True)
def clean_approval_text(self):
return self.cleaned_data["approval_text"].replace("\r", "")
@group_required('Area_Director','Secretariat')
def ballot_approvaltextREDESIGN(request, name):
def ballot_approvaltext(request, name):
"""Editing of approval text"""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.get_state("draft-iesg"):
@ -936,7 +879,7 @@ def ballot_approvaltextREDESIGN(request, name):
e = generate_approval_mail(request, doc)
# make sure form has the updated text
form = ApprovalTextForm(initial=dict(approval_text=existing.text))
form = ApprovalTextForm(initial=dict(approval_text=e.text))
can_announce = doc.get_state("draft-iesg").order > 19
need_intended_status = ""
@ -952,9 +895,6 @@ def ballot_approvaltextREDESIGN(request, name):
),
context_instance=RequestContext(request))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
ApprovalTextForm = ApprovalTextFormREDESIGN
ballot_approvaltext = ballot_approvaltextREDESIGN
@group_required('Secretariat')
def approve_ballot(request, name):

View file

@ -21,6 +21,7 @@ from django.middleware.gzip import GZipMiddleware
from django.db.models import Max
import debug
import urllib
from ietf.idtracker.models import InternetDraft
from ietf.utils.pipe import pipe
@ -427,22 +428,33 @@ def ical_agenda(request, num=None):
q = request.META.get('QUERY_STRING','') or ""
filter = q.lower().replace('%2c',',').split(',');
include = set(filter)
include_types = ["Plenary","Other"]
include_types = set(["Plenary","Other"])
exclude = []
# Process the special flags.
# "-wgname" will remove a working group from the output.
# "~Type" will add that type to the output.
# "-~Type" will remove that type from the output
# Current types are:
# Session, Other (default on), Break, Plenary (default on)
# Non-Working Group "wg names" include:
# edu, ietf, tools, iesg, iab
for item in include:
if item:
if item[0] == '-':
if item[0] == '-' and item[1] == '~':
include_types -= set([item[2:3].upper()+item[3:]])
elif item[0] == '-':
exclude.append(item[1:])
if item[0] == '~':
include_types.append(item[1:2].upper()+item[2:])
elif item[0] == '~':
include_types |= set([item[1:2].upper()+item[2:]])
timeslots = TimeSlot.objects.filter(Q(meeting__id = meeting.id),
Q(type__name__in = include_types) |
Q(session__group__acronym__in = filter) |
Q(session__group__parent__acronym__in = filter)
)#.exclude(Q(session__group__isnull = False),
).exclude(Q(session__group__acronym__in = exclude))
#.exclude(Q(session__group__isnull = False),
#Q(session__group__acronym__in = exclude) |
#Q(session__group__parent__acronym__in = exclude))

View file

@ -12,6 +12,8 @@ from django.template.loader import render_to_string
from django.utils.html import mark_safe
from django.core.urlresolvers import reverse as urlreverse
import debug
from ietf.idtracker.models import InternetDraft, IETFWG
from ietf.proceedings.models import Meeting
from ietf.submit.models import IdSubmissionDetail, TempIdAuthors, Preapproval
@ -204,6 +206,7 @@ class UploadForm(forms.Form):
txt_file.seek(0)
return self.draft
@debug.trace
def save(self):
for ext in ['txt', 'pdf', 'xml', 'ps']:
fd = self.cleaned_data[ext]
@ -334,11 +337,13 @@ class AutoPostForm(forms.Form):
'full_name': full_name})
return ''.join(buttons)
@debug.trace
def save(self, request):
self.save_submitter_info()
self.save_new_draft_info()
self.send_confirmation_mail(request)
@debug.trace
def send_confirmation_mail(self, request):
subject = 'Confirmation for Auto-Post of I-D %s' % self.draft.filename
from_email = settings.IDSUBMIT_FROM_EMAIL
@ -526,10 +531,12 @@ class MetaDataForm(AutoPostForm):
author_order=i + 1,
submission=draft)
@debug.trace
def save(self, request):
self.save_new_draft_info()
self.send_mail_to_secretariat(request)
@debug.trace
def send_mail_to_secretariat(self, request):
subject = 'Manual Post Requested for %s' % self.draft.filename
from_email = settings.IDSUBMIT_FROM_EMAIL

View file

@ -1,90 +0,0 @@
{% extends "base.html" %}
{% block title %}Ballot writeups for {{ doc }}{% endblock %}
{% block morecss %}
form #id_last_call_text {
width: 700px;
height: 300px;
}
form #id_ballot_writeup {
width: 700px;
height: 300px;
}
form #id_approval_text {
width: 700px;
height: 300px;
}
{% endblock %}
{% block content %}
<h1>Ballot writeups for {{ doc }}</h1>
<form action="" method="POST">
<h2>Last Call Announcement Text</h2>
{{ last_call_form.last_call_text }}
<p>{{ last_call_form.last_call_text.errors }}</p>
{% if can_request_last_call and need_intended_status %}
<p>You need to select intended status of {{ need_intended_status }} and regenerate last call text to request last call.</p>
{% endif %}
<div class="actions">
<a href="{{ doc.idinternal.get_absolute_url }}">Back</a>
<input type="submit" name="save_last_call_text" value="Save Last Call Text" />
<input type="submit" name="regenerate_last_call_text" value="Regenerate Last Call Text" />
{% if can_request_last_call and not need_intended_status %}
<input style="margin-left: 8px" type="submit" name="send_last_call_request" value="Save and Request Last Call" />
{% endif %}
</div>
</form>
<form action="" method="POST">
<h2>Ballot Writeup and Notes</h2>
<p>(Technical Summary, Working Group Summary, Document Quality,
Personnel, RFC Editor Note, IRTF Note, IESG Note, IANA Note)</p>
<p>This text will be appended to all announcements and messages to
the IRTF or RFC Editor.</p>
{{ ballot_writeup_form.ballot_writeup }}
<div class="actions">
<a href="{{ doc.idinternal.get_absolute_url }}">Back</a>
<input type="submit" name="save_ballot_writeup" value="Save Ballot Writeup" />
<input style="margin-left: 8px" type="submit" name="issue_ballot" value="Save and {% if ballot.ballot_issued %}Re-{% endif %}Issue Ballot" />
</div>
</form>
<form action="" method="POST">
<h2>Ballot Approval Announcement Text</h2>
<p>Sent after approval.</p>
{{ approval_text_form.approval_text }}
<div class="actions">
<a href="{{ doc.idinternal.get_absolute_url }}">Back</a>
<input type="submit" name="save_approval_text" value="Save Approval Announcement Text" />
<input type="submit" name="regenerate_approval_text" value="Regenerate Approval Announcement Text" />
</div>
</form>
{% load ietf_filters %}
{% if user|in_group:"Secretariat" %}
<p>
{% if can_make_last_call %}
<a href="{% url doc_make_last_call name=doc.filename %}">Make Last Call</a>
{% endif %}
{% if can_announce %}
<a href="{% url doc_approve_ballot name=doc.filename %}">Approve ballot</a>
{% endif %}
</p>
{% endif %}
{% endblock%}

View file

@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% else %}
{% if stream_info.stream.name == 'ISE' or stream_info.stream.name == 'IRTF' %}
{% if user|in_group:"Secretariat" and not info.conflict_reviews %}
<span id="doc_conflict_review_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}<span class="first-child"><a href="{{start_review_url}}">Begin IETF Conflict Review</a></span>{% endif %}</span>
<span id="doc_conflict_review_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}<span class="first-child"><a href="{{start_review_url}}">Begin IETF Conflict Review {% if not doc.underlying_document.intended_std_level %}(note that intended status is not set){% endif %}</a></span>{% endif %}</span>
{% endif %}
{% else %}
{% if stream_info.stream.name == 'IETF'%}{%if not doc.in_ietf_process %}

View file

@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<tr><td>Intended RFC status:</td><td>
{% with user|in_group:"Area_Director,Secretariat" as add_link %}
{% if add_link %}<a class="editlink" href="{% url doc_change_intended_status name=doc.draft_name %}">{% endif %}
{{ doc.underlying_document.intended_std_level|default:"-" }}
{{ doc.underlying_document.intended_std_level|default:"(None)" }}
{% if add_link %}</a>{% endif %}
{% endwith %}
</td></tr>
@ -142,7 +142,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<tr><td>Responsible AD:</td><td>
{% with user|in_group:"Area_Director,Secretariat" as add_link %}
{% if add_link %}<a class="editlink" href="{% url doc_change_ad name=doc.draft_name %}">{% endif %}
{% if doc.in_ietf_process %}{{ doc.ietf_process.ad_name|default:"-"|escape }}{%else%}-{%endif%}
{% if doc.in_ietf_process %}{{ doc.ietf_process.ad_name|default:"(None)"|escape }}{%else%}(None){%endif%}
{% if add_link %}</a>{% endif %}
{% endwith %}
</td></tr>

View file

@ -19,6 +19,8 @@ table#wg-selector { border:1px solid black; border-collapse:collapse; }
#wg-selector-triangle-right { vertical-align: text-top; }
#wg-selector-triangle-down { vertical-align: text-top; }
table#ics-preconfig { border:1px solid black; border-collapse:collapse; margin-top:24px; margin-bottom:24px;}
#weekview.hidden { display: none; }
#weekview { border: none; margin: 0 0 0 0;}
#ical-link.hidden { display: none; }
@ -88,6 +90,7 @@ img.hidden { display: none; }
var ical_link = document.getElementById('ical-link');
var ical_href = document.getElementById('ical-href');
lastfrag = frag;
var fragment = frag.split(',');
@ -163,7 +166,14 @@ img.hidden { display: none; }
}
}
// Handle special cases (checkboxes)
var special = ['edu','ietf','tools','iesg','iab'];
var re3 = RegExp("^(" + fragment.join('|') + ")$");
for (i in special)
{
var include = document.getElementById("include-"+special[i]);
include.checked = ! re3.test("\-"+special[i]);
}
}
/* Resizes an IFRAME to fit its contents. */
@ -203,6 +213,26 @@ img.hidden { display: none; }
}
}
function add_hash_item(item)
{
if (window.location.hash.replace("#","").length == 0)
{
window.location.hash = item;
}
else
{
window.location.hash += "," + item;
}
window.location.hash = window.location.hash.replace(/^#?,/,'');
}
function remove_hash_item(item)
{
var re = new RegExp('(^|#|,)' + item + "(,|$)");
window.location.hash = window.location.hash.replace(re,"$2")
window.location.hash = window.location.hash.replace(/^#?,/,'');
}
function toggle(selection)
{
var active = selection.className;
@ -210,26 +240,28 @@ img.hidden { display: none; }
if (active == "selected")
{
var re = new RegExp('(^|#|,)' + wg + "(,|$)");
window.location.hash = window.location.hash.replace(re,"$2")
remove_hash_item(wg);
}
else
{
if (window.location.hash.replace("#","").length == 0)
{
window.location.hash = wg;
}
else
{
window.location.hash += "," + wg;
}
add_hash_item(wg);
}
window.location.hash = window.location.hash.replace(/^#?,/,'');
setGroupState();
}
function toggle_special(checkbox)
{
var special = checkbox.id.replace('include-','');
if (checkbox.checked)
{
remove_hash_item("-"+special);
}
else
{
add_hash_item("-"+special);
}
}
function toggle_wg_selector ()
{
var wg_selector = document.getElementById('wg-selector');
@ -247,6 +279,7 @@ img.hidden { display: none; }
triangle_right.className = '';
triangle_down.className = 'hidden';
}
setGroupState();
}
</script>
@ -285,13 +318,31 @@ You can customize the agenda below to show only selected working group sessions.
<div id='selector-{{wg.acronym}}' class="unselected" onclick="toggle(this)">{% if wg.state.name = "BOF" %}<i>{{wg.acronym}}</i>{% else %}{{wg.acronym}}{% endif %}</div>{% endfor %}
</td>
</tr>
<tr><td align="center" colspan="{{area_list.count}}"><i>Groups displayed in italics are BOFs</i></td></tr>
<tr><td align="center" colspan="{{area_list.count}}">
Also show:
<input type="checkbox" class="include-checkbox" id="include-edu" onchange="toggle_special(this)"/>EDU &#8226;
<input type="checkbox" class="include-checkbox" id="include-ietf" onchange="toggle_special(this)"/>IETF &#8226;
<input type="checkbox" class="include-checkbox" id="include-tools" onchange="toggle_special(this)"/>Tools &#8226;
<input type="checkbox" class="include-checkbox" id="include-iesg" onchange="toggle_special(this)"/>IESG &#8226;
<input type="checkbox" class="include-checkbox" id="include-iab" onchange="toggle_special(this)"/>IAB
<!-- </td></tr>
<tr><td align="center" colspan="{{area_list.count}}">
-->
<br/><i>Groups displayed in italics are BOFs</i></td></tr>
</table>
<div id="ical-link" class="hidden"><span style="font-size:150%">Week View</span><br/><a id="ical-href" href="{% url ietf.meeting.views.ical_agenda num=meeting.number %}"><em>Download as an .ical file</em></a></div>
<div id="ical-link" class="hidden"><span style="font-size:150%">Week View</span><br/><a id="ical-href" href="{% url ietf.meeting.views.ical_agenda num=meeting.number %}"><em>Download as an .ics file</em></a></div>
<iframe id="weekview" class="hidden" width="100%" height="600px" src="about:blank"></iframe>
<table width="100%" id="ics-preconfig"><tr><td align="center">
Preconfigured .ics links:
{% for area in area_list %}
<a href="{% url ietf.meeting.views.ical_agenda num=meeting.number %}?{{area|upper}},-~Other,-~Plenary">{{area|upper}}</a> &#8226;
{% endfor %}
<a href="{% url ietf.meeting.views.ical_agenda num=meeting.number %}">Non-Area Events</a>
</td></tr></table>
{% if meeting.agenda_note %}<h2 class="ietf-divider" style="background-color: #C00; margin-top: 2em; margin-bottom: 0;">{{ meeting.agenda_note|safe }}</h2>{% endif %}
<table id="agenda" width="100%">

View file

@ -9,7 +9,7 @@ var items = new Array();
{% autoescape off %}
{% for slot in timeslots %} {% if slot.type.name in render_types %}
items.push({day:{{slot.time|date:"w"}}, time:"{{slot.time|date:"Hi"}}-{{slot.end_time|date:"Hi"}}", duration:{{slot.duration.seconds}}, time_id:"{{slot.time|date:"mdHi"}}", type:"{{slot.type}}", {% if slot.session.name %}name:"{{slot.session.name}}",{% else %}{% if slot.type.name == "Break" %}name:"{{slot.name}}", area:"break", wg:"break",{% else %}name:"{{slot.session.group.name}}{%if slot.session.group.state.name = "BOF"%} BOF{%endif%}",wg:"{{slot.session.group.acronym}}",area:"{{slot.session.group.parent.acronym}}",{% endif %}{% endif %} {% if slot.show_location %}room:"{{slot.get_location}}",{% endif %} dayname:"{{ slot.time|date:"l"|upper }}, {{ slot.time|date:"F j, Y" }}"{% if slot.session.agenda %}, agenda:"http://www.ietf.org{{slot.session.agenda.get_absolute_url}}"{% endif %} });{% endif %}{% endfor %}
items.push({key:"{{slot.pk}}",day:{{slot.time|date:"w"}}, time:"{{slot.time|date:"Hi"}}-{{slot.end_time|date:"Hi"}}", duration:{{slot.duration.seconds}}, time_id:"{{slot.time|date:"mdHi"}}", type:"{{slot.type}}", {% if slot.session.name %}name:"{{slot.session.name}}",{% if slot.session.group.acronym %} wg:"{{slot.session.group.acronym}}",{%endif%}{% else %}{% if slot.type.name == "Break" %}name:"{{slot.name}}", area:"break", wg:"break",{% else %}name:"{{slot.session.group.name}}{%if slot.session.group.state.name = "BOF"%} BOF{%endif%}",wg:"{{slot.session.group.acronym}}",state:"{{slot.session.group.state}}",area:"{{slot.session.group.parent.acronym}}",{% endif %}{% endif %} {% if slot.show_location %}room:"{{slot.get_location}}",{% endif %} dayname:"{{ slot.time|date:"l"|upper }}, {{ slot.time|date:"F j, Y" }}"{% if slot.session.agenda %}, agenda:"http://www.ietf.org{{slot.session.agenda.get_absolute_url}}"{% endif %} });{% endif %}{% endfor %}
{% endautoescape %}
/* Saturday events need to be moved to the day -1 */
@ -63,8 +63,40 @@ var lastwidth;
var padding = 2;
var border = 1;
var include = Array();
setInterval("animate()",50);
function is_visible(item)
{
// "-wgname" will remove a working group from the output.
// "~Type" will add that type to the output.
// "-~Type" will remove that type from the output
// "@bof" will include all BOFs
// Current types are:
// Session, Other, Break, Plenary
if ("wg" in item)
{
if (include[(item.wg).toLowerCase()]) { return true; }
if (include["-"+(item.wg).toLowerCase()]) { return false; }
}
if ("state" in item)
{
if (include["@"+(item.state).toLowerCase()]) { return true; }
}
if (include["~"+(item.type).toLowerCase()]) { return true; }
if (include["-~"+(item.type).toLowerCase()]) { return false; }
if ("area" in item)
{
if (include[(item.area).toLowerCase()]) { return true; }
}
if (item.type === "Plenary") { return true; }
if (item.type === "Other") { return true; }
return false;
}
function draw_calendar()
{
window.setTimeout("draw_calendar()",1000);
@ -88,7 +120,7 @@ function draw_calendar()
var day_start = 0;
var day_end = 0;
var include = Array();
include = [];
var frag = window.location.hash.replace("#",'').split(',');
for (i = 0; i < frag.length; i++)
@ -99,8 +131,11 @@ function draw_calendar()
/* Find our boundaries */
for (i = 0; i < items.length; i++)
{
if (is_visible(items[i]))
/*
if (!("wg" in items[i]) || (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()]))
*/
{
var start_time = parseInt(items[i].time.substr(0,2),10) * 60 +
parseInt(items[i].time.substr(2,2),10);
@ -207,8 +242,11 @@ function draw_calendar()
for (i = 0; i < items.length; i++)
{
if (!("wg" in items[i])|| (include[(items[i].wg).toLowerCase()]
if (is_visible(items[i]))
/*
if (!("wg" in items[i]) || (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()]))
*/
{
var start_time = parseInt(items[i].time.substr(0,2),10) * 60 +
parseInt(items[i].time.substr(2,2),10);

View file

@ -287,13 +287,13 @@ class ManageWriteupTestCase(django.test.TestCase):
confirm="1",
followup="1",
comment="Starting on write up",
modify_tag="Modify"))
complete_tag="Modify"))
self.assertEquals(r.status_code, 200)
e = draft.latest_event(WriteupDocEvent, type="changed_protocol_writeup")
self.assertTrue(e)
self.assertEquals(e.text, "New writeup")
self.assertEquals(e.by.user.username, "secretary")
self.assertTrue(draft.tags.filter(slug="sheph-u"))
self.assertFalse(draft.tags.filter(slug="sheph-u"))
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:

204
magic.py Normal file
View file

@ -0,0 +1,204 @@
#!/usr/bin/env python
'''
Python bindings for libmagic
'''
import ctypes
from ctypes import *
from ctypes.util import find_library
def _init():
"""
Loads the shared library through ctypes and returns a library
L{ctypes.CDLL} instance
"""
return ctypes.cdll.LoadLibrary(find_library('magic'))
_libraries = {}
_libraries['magic'] = _init()
# Flag constants for open and setflags
MAGIC_NONE = NONE = 0
MAGIC_DEBUG = DEBUG = 1
MAGIC_SYMLINK = SYMLINK = 2
MAGIC_COMPRESS = COMPRESS = 4
MAGIC_DEVICES = DEVICES = 8
MAGIC_MIME_TYPE = MIME_TYPE = 16
MAGIC_CONTINUE = CONTINUE = 32
MAGIC_CHECK = CHECK = 64
MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
MAGIC_RAW = RAW = 256
MAGIC_ERROR = ERROR = 512
MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
MAGIC_MIME = MIME = 1040
MAGIC_APPLE = APPLE = 2048
MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
class magic_set(Structure):
pass
magic_set._fields_ = []
magic_t = POINTER(magic_set)
_open = _libraries['magic'].magic_open
_open.restype = magic_t
_open.argtypes = [c_int]
_close = _libraries['magic'].magic_close
_close.restype = None
_close.argtypes = [magic_t]
_file = _libraries['magic'].magic_file
_file.restype = c_char_p
_file.argtypes = [magic_t, c_char_p]
_descriptor = _libraries['magic'].magic_descriptor
_descriptor.restype = c_char_p
_descriptor.argtypes = [magic_t, c_int]
_buffer = _libraries['magic'].magic_buffer
_buffer.restype = c_char_p
_buffer.argtypes = [magic_t, c_void_p, c_size_t]
_error = _libraries['magic'].magic_error
_error.restype = c_char_p
_error.argtypes = [magic_t]
_setflags = _libraries['magic'].magic_setflags
_setflags.restype = c_int
_setflags.argtypes = [magic_t, c_int]
_load = _libraries['magic'].magic_load
_load.restype = c_int
_load.argtypes = [magic_t, c_char_p]
_compile = _libraries['magic'].magic_compile
_compile.restype = c_int
_compile.argtypes = [magic_t, c_char_p]
_check = _libraries['magic'].magic_check
_check.restype = c_int
_check.argtypes = [magic_t, c_char_p]
_list = _libraries['magic'].magic_list
_list.restype = c_int
_list.argtypes = [magic_t, c_char_p]
_errno = _libraries['magic'].magic_errno
_errno.restype = c_int
_errno.argtypes = [magic_t]
class Magic(object):
def __init__(self, ms):
self._magic_t = ms
def close(self):
"""
Closes the magic database and deallocates any resources used.
"""
_close(self._magic_t)
def file(self, file):
"""
Returns a textual description of the contents of the argument passed
as a filename or None if an error occurred and the MAGIC_ERROR flag
is set. A call to errno() will return the numeric error code.
"""
return _file(self._magic_t, file)
def descriptor(self, fd):
"""
Like the file method, but the argument is a file descriptor.
"""
return _descriptor(self._magic_t, fd)
def buffer(self, buf):
"""
Returns a textual description of the contents of the argument passed
as a buffer or None if an error occurred and the MAGIC_ERROR flag
is set. A call to errno() will return the numeric error code.
"""
return _buffer(self._magic_t, buf, len(buf))
def error(self):
"""
Returns a textual explanation of the last error or None
if there was no error.
"""
return _error(self._magic_t)
def setflags(self, flags):
"""
Set flags on the magic object which determine how magic checking behaves;
a bitwise OR of the flags described in libmagic(3), but without the MAGIC_
prefix.
Returns -1 on systems that don't support utime(2) or utimes(2)
when PRESERVE_ATIME is set.
"""
return _setflags(self._magic_t, flags)
def load(self, file=None):
"""
Must be called to load entries in the colon separated list of database files
passed as argument or the default database file if no argument before
any magic queries can be performed.
Returns 0 on success and -1 on failure.
"""
return _load(self._magic_t, file)
def compile(self, dbs):
"""
Compile entries in the colon separated list of database files
passed as argument or the default database file if no argument.
Returns 0 on success and -1 on failure.
The compiled files created are named from the basename(1) of each file
argument with ".mgc" appended to it.
"""
return _compile(self._magic_t, dbs)
def check(self, dbs):
"""
Check the validity of entries in the colon separated list of
database files passed as argument or the default database file
if no argument.
Returns 0 on success and -1 on failure.
"""
return _check(self._magic_t, dbs)
def list(self, dbs):
"""
Check the validity of entries in the colon separated list of
database files passed as argument or the default database file
if no argument.
Returns 0 on success and -1 on failure.
"""
return _list(self._magic_t, dbs)
def errno(self):
"""
Returns a numeric error code. If return value is 0, an internal
magic error occurred. If return value is non-zero, the value is
an OS error code. Use the errno module or os.strerror() can be used
to provide detailed error information.
"""
return _errno(self._magic_t)
def open(flags):
"""
Returns a magic object on success and None on failure.
Flags argument as for setflags.
"""
return Magic(_open(flags))