diff --git a/debug.py b/debug.py index b515e0816..c3a1c5087 100644 --- a/debug.py +++ b/debug.py @@ -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 diff --git a/ietf/idrfc/views_ballot.py b/ietf/idrfc/views_ballot.py index 2137217a4..66b51ef67 100644 --- a/ietf/idrfc/views_ballot.py +++ b/ietf/idrfc/views_ballot.py @@ -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): diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 2d1dee611..3885131aa 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -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)) diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index be731784e..6b3abe721 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -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 diff --git a/ietf/templates/idrfc/ballot_writeups.html b/ietf/templates/idrfc/ballot_writeups.html deleted file mode 100644 index 1b41eaa4d..000000000 --- a/ietf/templates/idrfc/ballot_writeups.html +++ /dev/null @@ -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 %} -

Ballot writeups for {{ doc }}

- -
-

Last Call Announcement Text

- - {{ last_call_form.last_call_text }} - -

{{ last_call_form.last_call_text.errors }}

- - {% if can_request_last_call and need_intended_status %} -

You need to select intended status of {{ need_intended_status }} and regenerate last call text to request last call.

- {% endif %} - -
- Back - - - {% if can_request_last_call and not need_intended_status %} - - {% endif %} -
-
- - -
-

Ballot Writeup and Notes

- -

(Technical Summary, Working Group Summary, Document Quality, - Personnel, RFC Editor Note, IRTF Note, IESG Note, IANA Note)

- -

This text will be appended to all announcements and messages to - the IRTF or RFC Editor.

- - {{ ballot_writeup_form.ballot_writeup }} - -
- Back - - -
-
- - -
-

Ballot Approval Announcement Text

- -

Sent after approval.

- - {{ approval_text_form.approval_text }} - -
- Back - - -
-
- -{% load ietf_filters %} -{% if user|in_group:"Secretariat" %} -

-{% if can_make_last_call %} -Make Last Call -{% endif %} - -{% if can_announce %} -Approve ballot -{% endif %} -

-{% endif %} -{% endblock%} diff --git a/ietf/templates/idrfc/doc_tab_document.html b/ietf/templates/idrfc/doc_tab_document.html index 62256bb3a..e4f91e1bd 100644 --- a/ietf/templates/idrfc/doc_tab_document.html +++ b/ietf/templates/idrfc/doc_tab_document.html @@ -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 %} -{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}Begin IETF Conflict Review{% endif %} +{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}Begin IETF Conflict Review {% if not doc.underlying_document.intended_std_level %}(note that intended status is not set){% endif %}{% endif %} {% endif %} {% else %} {% if stream_info.stream.name == 'IETF'%}{%if not doc.in_ietf_process %} diff --git a/ietf/templates/idrfc/doc_tab_document_id.html b/ietf/templates/idrfc/doc_tab_document_id.html index 90a621879..ef8e4107a 100644 --- a/ietf/templates/idrfc/doc_tab_document_id.html +++ b/ietf/templates/idrfc/doc_tab_document_id.html @@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Intended RFC status: {% with user|in_group:"Area_Director,Secretariat" as add_link %} {% if add_link %}{% endif %} -{{ doc.underlying_document.intended_std_level|default:"-" }} +{{ doc.underlying_document.intended_std_level|default:"(None)" }} {% if add_link %}{% endif %} {% endwith %} @@ -142,7 +142,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Responsible AD: {% with user|in_group:"Area_Director,Secretariat" as add_link %} {% if add_link %}{% 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 %}{% endif %} {% endwith %} diff --git a/ietf/templates/meeting/agenda.html b/ietf/templates/meeting/agenda.html index d600fe9ce..4a6071323 100644 --- a/ietf/templates/meeting/agenda.html +++ b/ietf/templates/meeting/agenda.html @@ -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(); } @@ -285,13 +318,31 @@ You can customize the agenda below to show only selected working group sessions.
{% if wg.state.name = "BOF" %}{{wg.acronym}}{% else %}{{wg.acronym}}{% endif %}
{% endfor %} - Groups displayed in italics are BOFs + + Also show: + EDU • + IETF • + Tools • + IESG • + IAB + +
Groups displayed in italics are BOFs - + +
+ Preconfigured .ics links: + {% for area in area_list %} + {{area|upper}} • + {% endfor %} + Non-Area Events +
+ {% if meeting.agenda_note %}

{{ meeting.agenda_note|safe }}

{% endif %} diff --git a/ietf/templates/meeting/week-view.html b/ietf/templates/meeting/week-view.html index ddb4384dc..8b68e9b9f 100644 --- a/ietf/templates/meeting/week-view.html +++ b/ietf/templates/meeting/week-view.html @@ -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); diff --git a/ietf/wgchairs/tests.py b/ietf/wgchairs/tests.py index 7e9275d27..14b77a0e0 100644 --- a/ietf/wgchairs/tests.py +++ b/ietf/wgchairs/tests.py @@ -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: diff --git a/magic.py b/magic.py new file mode 100644 index 000000000..41a42ee55 --- /dev/null +++ b/magic.py @@ -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))