File indexing completed on 2024-11-03 05:13:00
0001 # -*- coding: UTF-8 -*- 0002 0003 """ 0004 Set elements of the PO header. 0005 0006 Documented in C{doc/user/sieving.docbook}. 0007 0008 @author: Chusslove Illich (Часлав Илић) <caslav.ilic@gmx.net> 0009 @license: GPLv3 0010 """ 0011 0012 import time 0013 import re 0014 0015 from pology import _, n_ 0016 from pology.report import report, warning 0017 from pology.resolve import expand_vars 0018 from pology.sieve import SieveError 0019 0020 0021 def setup_sieve (p): 0022 0023 p.set_desc(_("@info sieve discription", 0024 "Set elements of the PO header." 0025 "\n\n" 0026 "Sometimes a header field needs to be modified, added or removed " 0027 "in many catalogs, and this sieve serves that purpose." 0028 "\n\n" 0029 "%%-character in the value is used to expand known variables. " 0030 "Currently these are: %%%(var1)s - name of the catalog. " 0031 "If literal %% is needed (e.g. in plural forms header), " 0032 "it can be escaped as %%%%.", 0033 var1="poname" 0034 )) 0035 0036 p.add_param("field", str, multival=True, 0037 metavar=_("@info sieve parameter value placeholder", 0038 "FIELD:VALUE"), 0039 desc=_("@info sieve parameter discription", 0040 "Set a header field to the given value. " 0041 "This parameter can be repeated, to set several fields in single run." 0042 )) 0043 p.add_param("create", bool, defval=False, 0044 desc=_("@info sieve parameter discription", 0045 "Add the field if not present " 0046 "(by default the field value is set only if the field already exists " 0047 "in the header)." 0048 )) 0049 p.add_param("after", str, 0050 metavar=_("@info sieve parameter value placeholder", "FIELD"), 0051 desc=_("@info sieve parameter discription", 0052 "When the new field is being added, add it after this field. " 0053 "If such field does not exist, the new field is added as the last one." 0054 )) 0055 p.add_param("before", str, 0056 metavar=_("@info sieve parameter value placeholder", "FIELD"), 0057 desc=_("@info sieve parameter discription", 0058 "When the new field is being added, add it before this field. " 0059 "If such field does not exist, the new field is added as the last one." 0060 )) 0061 p.add_param("reorder", bool, defval=False, 0062 desc=_("@info sieve parameter discription", 0063 "If the field to be set is present, but not in the order implied by " 0064 "'%(par1)s' and '%(par2)s' parameters, reinsert it accordingly.", 0065 par1="after", par2="before" 0066 )) 0067 p.add_param("remove", str, multival=True, 0068 metavar=_("@info sieve parameter value placeholder", "FIELD"), 0069 desc=_("@info sieve parameter discription", 0070 "Remove the field." 0071 )) 0072 p.add_param("removerx", str, multival=True, 0073 metavar=_("@info sieve parameter value placeholder", "REGEX"), 0074 desc=_("@info sieve parameter discription", 0075 "Remove all fields matching the regular expression. " 0076 "Matching is not case-sensitive." 0077 )) 0078 p.add_param("title", str, multival=True, 0079 metavar=_("@info sieve parameter value placeholder", "VALUE"), 0080 desc=_("@info sieve parameter discription", 0081 "Set title comment to the given value." 0082 "Can be repeated to set several title lines. " 0083 "All existing title lines are removed before setting the new ones." 0084 )) 0085 p.add_param("rmtitle", bool, defval=False, 0086 desc=_("@info sieve parameter discription", 0087 "Remove title comments." 0088 )) 0089 p.add_param("copyright", str, 0090 metavar=_("@info sieve parameter value placeholder", "VALUE"), 0091 desc=_("@info sieve parameter discription", 0092 "Set copyright comment to the given value." 0093 )) 0094 p.add_param("rmcopyright", bool, defval=False, 0095 desc=_("@info sieve parameter discription", 0096 "Remove the copyright comment." 0097 )) 0098 p.add_param("license", str, 0099 metavar=_("@info sieve parameter value placeholder", "VALUE"), 0100 desc=_("@info sieve parameter discription", 0101 "Set license comment to the given value." 0102 )) 0103 p.add_param("rmlicense", bool, defval=False, 0104 desc=_("@info sieve parameter discription", 0105 "Remove the license comment." 0106 )) 0107 p.add_param("author", str, multival=True, 0108 metavar=_("@info sieve parameter value placeholder", "VALUE"), 0109 desc=_("@info sieve parameter discription", 0110 "Set author comment to the given value. " 0111 "Can be repeated to set several authors. " 0112 "All existing authors are removed before setting the new ones." 0113 )) 0114 p.add_param("rmauthor", bool, defval=False, 0115 desc=_("@info sieve parameter discription", 0116 "Remove author comments." 0117 )) 0118 p.add_param("comment", str, multival=True, 0119 metavar=_("@info sieve parameter value placeholder", "VALUE"), 0120 desc=_("@info sieve parameter discription", 0121 "Set free comment to the given value. " 0122 "Can be repeated to set several free comment lines. " 0123 "All existing comment lines are removed before setting the new ones." 0124 )) 0125 p.add_param("rmcomment", bool, defval=False, 0126 desc=_("@info sieve parameter discription", 0127 "Remove free comments." 0128 )) 0129 p.add_param("rmallcomm", bool, defval=False, 0130 desc=_("@info sieve parameter discription", 0131 "Remove all header comments." 0132 )) 0133 0134 0135 class Sieve (object): 0136 0137 def __init__ (self, params): 0138 0139 # Parse field setting specifications. 0140 self.fields_values = [] 0141 for field_value_str in (params.field or []): 0142 field_value = field_value_str.split(":", 1) 0143 if len(field_value) != 2: 0144 raise SieveError( 0145 _("@info", 0146 "Invalid specification '%(spec)s' " 0147 "of header field and value.", 0148 spec=field_value_str)) 0149 self.fields_values.append(field_value) 0150 0151 # Set fields in reverse, so that 'after' and 'before' parameters 0152 # are followed by the order of appearance of fields in command line. 0153 if params.after or params.before: 0154 self.fields_values.reverse() 0155 0156 # Prepare matching for field removal. 0157 if params.removerx is not None: 0158 rxs = [] 0159 for rxstr in params.removerx: 0160 try: 0161 rx = re.compile(rxstr, re.U|re.I) 0162 except: 0163 raise SieveError( 0164 _("@info", 0165 "Invalid regular expression '%(regex)s' " 0166 "for removing fields.", 0167 regex=rxstr)) 0168 rxs.append(rx) 0169 params.removerx = rxs 0170 0171 # Check validity of comment values. 0172 for title in (params.title or []): 0173 if re.search(r"copyright|©|\(C\)|license|<.*?@.*?>", 0174 title, re.I|re.U): 0175 raise SieveError( 0176 _("@info", 0177 "Invalid value '%(val)s' for title comment " 0178 "(it contains some elements appropriate " 0179 "for other types of comments).", 0180 val=title)) 0181 if params.copyright is not None: 0182 if not re.search(r"copyright|©|\(C\)", params.copyright, re.I|re.U): 0183 raise SieveError( 0184 _("@info", 0185 "Invalid value '%(val)s' for copyright comment " 0186 "(missing the word 'copyright'?).", 0187 val=params.copyright)) 0188 if params.license is not None: 0189 if not re.search(r"license", params.license, re.I): 0190 raise SieveError( 0191 _("@info", 0192 "Invalid value '%(val)s' for license comment " 0193 "(missing the word 'license'?).", 0194 val=params.license)) 0195 for author in (params.author or []): 0196 if not re.search(r"<.*?@.*?>", author): 0197 raise SieveError( 0198 _("@info", 0199 "Invalid value '%(val)s' for author comment " 0200 "(missing the email address?).", 0201 val=author)) 0202 self.p = params 0203 0204 0205 def process_header (self, hdr, cat): 0206 0207 pvars = {"poname" : cat.name} 0208 0209 for rmname in self.p.remove or []: 0210 hdr.remove_field(rmname) 0211 for rmrx in self.p.removerx or []: 0212 to_remove = set() 0213 for name, value in hdr.field: 0214 if name not in to_remove and rmrx.search(name): 0215 to_remove.add(name) 0216 for name in to_remove: 0217 hdr.remove_field(name) 0218 0219 for field, value in self.fields_values: 0220 if self.p.create or hdr.select_fields(field): 0221 hdr.set_field(field, expand_vars(value, pvars), 0222 after=self.p.after, before=self.p.before, 0223 reorder=self.p.reorder) 0224 0225 if self.p.rmtitle or self.p.rmallcomm: 0226 hdr.title[:] = [] 0227 if self.p.title is not None: 0228 hdr.title[:] = [expand_vars(x, pvars) for x in self.p.title] 0229 if self.p.rmcopyright or self.p.rmallcomm: 0230 hdr.copyright = None 0231 if self.p.copyright is not None: 0232 hdr.copyright = expand_vars(self.p.copyright, pvars) 0233 if self.p.rmlicense or self.p.rmallcomm: 0234 hdr.license = None 0235 if self.p.license is not None: 0236 hdr.license = expand_vars(self.p.license, pvars) 0237 if self.p.rmauthor or self.p.rmallcomm: 0238 hdr.author[:] = [] 0239 if self.p.author is not None: 0240 hdr.author[:] = [expand_vars(x, pvars) for x in self.p.author] 0241 if self.p.rmcomment or self.p.rmallcomm: 0242 hdr.comment[:] = [] 0243 if self.p.comment is not None: 0244 hdr.comment[:] = [expand_vars(x, pvars) for x in self.p.comment] 0245