Adium

Ticket #6091: KGProfanityFilter.diff

File KGProfanityFilter.diff, 10.9 kB (added by kiel, 2 years ago)

Comments on this draft profanity filter, anyone?

  • Adium.xcodeproj/project.pbxproj

    old new  
    11011101                9E20910E06A601AF00E33E27 /* CBStatusMenuItemController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E791DA40577094400547562 /* CBStatusMenuItemController.m */; }; 
    11021102                9E20911006A601B200E33E27 /* CBStatusMenuItemPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E791D9505768B7A00547562 /* CBStatusMenuItemPlugin.m */; }; 
    11031103                9E217B7B06A74CA8002A3F27 /* StatusMenuItemDefaultPrefs.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9E217B7706A74CA7002A3F27 /* StatusMenuItemDefaultPrefs.plist */; }; 
     1104                9E7B66EF0B733E3800DE6D5F /* KGProfanityFilterPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9E7B66ED0B733E3800DE6D5F /* KGProfanityFilterPlugin.h */; }; 
     1105                9E7B66F00B733E3800DE6D5F /* KGProfanityFilterPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E7B66EE0B733E3800DE6D5F /* KGProfanityFilterPlugin.m */; }; 
    11041106                9ECB03E709F2A9D900996F44 /* AIDictionaryDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 9ECB03E309F2A9D800996F44 /* AIDictionaryDebug.m */; }; 
    11051107                9ECB03E909F2A9D900996F44 /* AIXMLAppender.m in Sources */ = {isa = PBXBuildFile; fileRef = 9ECB03E509F2A9D800996F44 /* AIXMLAppender.m */; }; 
    11061108                9EF0DBFA09D944C200FBCC1E /* Resources/block.png in Resources */ = {isa = PBXBuildFile; fileRef = 9EF0DBF309D944A300FBCC1E /* Resources/block.png */; }; 
     
    14871489                        files = ( 
    14881490                                F51BCE390A156312000FDC06 /* AdiumSpotlightImporter.mdimporter in CopyFiles */, 
    14891491                                11F1460B0B546C1200CA91F6 /* AIMenuBarIcons.h in CopyFiles */, 
     1492                                9E7B66EF0B733E3800DE6D5F /* KGProfanityFilterPlugin.h in CopyFiles */, 
    14901493                        ); 
    14911494                        runOnlyForDeploymentPostprocessing = 0; 
    14921495                }; 
     
    34263429                9E791D9505768B7A00547562 /* CBStatusMenuItemPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CBStatusMenuItemPlugin.m; path = "Plugins/Status Menu Item/CBStatusMenuItemPlugin.m"; sourceTree = "<group>"; }; 
    34273430                9E791DA30577094300547562 /* CBStatusMenuItemController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CBStatusMenuItemController.h; path = "Plugins/Status Menu Item/CBStatusMenuItemController.h"; sourceTree = "<group>"; }; 
    34283431                9E791DA40577094400547562 /* CBStatusMenuItemController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CBStatusMenuItemController.m; path = "Plugins/Status Menu Item/CBStatusMenuItemController.m"; sourceTree = "<group>"; }; 
     3432                9E7B66ED0B733E3800DE6D5F /* KGProfanityFilterPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KGProfanityFilterPlugin.h; path = Source/KGProfanityFilterPlugin.h; sourceTree = "<group>"; }; 
     3433                9E7B66EE0B733E3800DE6D5F /* KGProfanityFilterPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KGProfanityFilterPlugin.m; path = Source/KGProfanityFilterPlugin.m; sourceTree = "<group>"; }; 
    34293434                9E95316703C8E0BE00415B22 /* AIDockController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AIDockController.h; path = Source/AIDockController.h; sourceTree = "<group>"; }; 
    34303435                9E95316903C8E0C700415B22 /* AIDockController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AIDockController.m; path = Source/AIDockController.m; sourceTree = "<group>"; }; 
    34313436                9EA125E8055B630900ECF349 /* CBGaimOscarAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CBGaimOscarAccount.m; path = "Plugins/Gaim Service/CBGaimOscarAccount.m"; sourceTree = "<group>"; }; 
     
    44834488                                F1D0C631051AC2380000000E /* Message Alias Support */, 
    44844489                                6E5A43DC0611604B0078C342 /* Message History */, 
    44854490                                F569E38102CA876501A8010A /* Message Window Interface */, 
     4491                                9E7B66EC0B733DB400DE6D5F /* Profanity Filter */, 
    44864492                                343022240AB4763D0082CF7C /* Removal of NULs in Messages */, 
    44874493                                34A65AF606A5A0C400898470 /* Safari Link Toolbar Item */, 
    44884494                                34DFF46607A5EAC800B92233 /* Secure Messaging */, 
     
    64146420                        name = "Status Menu Item"; 
    64156421                        sourceTree = "<group>"; 
    64166422                }; 
     6423                9E7B66EC0B733DB400DE6D5F /* Profanity Filter */ = { 
     6424                        isa = PBXGroup; 
     6425                        children = ( 
     6426                                9E7B66ED0B733E3800DE6D5F /* KGProfanityFilterPlugin.h */, 
     6427                                9E7B66EE0B733E3800DE6D5F /* KGProfanityFilterPlugin.m */, 
     6428                        ); 
     6429                        name = "Profanity Filter"; 
     6430                        sourceTree = "<group>"; 
     6431                }; 
    64176432                9EB3C52304F94DB7001D1F74 /* Migration Assistant */ = { 
    64186433                        isa = PBXGroup; 
    64196434                        children = ( 
     
    85308545                                345EE2DF0AD057FA003F396A /* AIContactInfoImageViewWithImagePicker.m in Sources */, 
    85318546                                377ED2670AED59E600CB7BDF /* TabsAdvancedPreferences.m in Sources */, 
    85328547                                11F1460C0B546C1200CA91F6 /* AIMenuBarIcons.m in Sources */, 
     8548                                9E7B66F00B733E3800DE6D5F /* KGProfanityFilterPlugin.m in Sources */, 
    85338549                        ); 
    85348550                        runOnlyForDeploymentPostprocessing = 0; 
    85358551                }; 
  • Source/KGProfanityFilterPlugin.h

    old new  
     1// 
     2//  KGProfanityFilterPlugin.h 
     3//  Adium 
     4// 
     5//  Created by Kiel Gillard on 2/02/07. 
     6//  Copyright 2007 __MyCompanyName__. All rights reserved. 
     7// 
     8 
     9#import <Adium/AIPlugin.h> 
     10 
     11@protocol AIContentFilter; 
     12 
     13@interface KGProfanityFilterPlugin : AIPlugin <AIContentFilter> { 
     14        NSSet *profanities; 
     15        bool shouldFilterIncomingProfanities; 
     16        bool shouldFilterOutgoingProfanities; 
     17} 
     18 
     19@end 
  • Source/KGProfanityFilterPlugin.m

    old new  
     1// 
     2//  KGProfanityFilterPlugin.m 
     3//  Adium 
     4// 
     5//  Created by Kiel Gillard on 2/02/07. 
     6//  Copyright 2007 __MyCompanyName__. All rights reserved. 
     7// 
     8 
     9#import "KGProfanityFilterPlugin.h" 
     10#import <Adium/AIContentControllerProtocol.h> 
     11#import "AIPreferenceController.h" 
     12 
     13#define FILTER_INCOMING_PREFERENCE_KEY @"FILTER_PROFAINE_INCOMING_CONTENT" 
     14#define FILTER_OUTGOING_PREFERENCE_KEY @"FILTER_PROFAINE_OUTGOING_CONTENT" 
     15#define PROFANITY_PREFERENCE_GROUP_KEY @"Profanity" 
     16 
     17@implementation KGProfanityFilterPlugin 
     18 
     19- (void)installPlugin 
     20{ 
     21        //we don't want to filter the profanities by default 
     22        shouldFilterIncomingProfanities = [(NSNumber *)[[adium preferenceController] preferenceForKey:FILTER_INCOMING_PREFERENCE_KEY  
     23                                                                                                                                                                                        group:PROFANITY_PREFERENCE_GROUP_KEY] boolValue]; 
     24        shouldFilterOutgoingProfanities = [(NSNumber *)[[adium preferenceController] preferenceForKey:FILTER_OUTGOING_PREFERENCE_KEY  
     25                                                                                                                                                                                        group:PROFANITY_PREFERENCE_GROUP_KEY] boolValue]; 
     26         
     27        /* presumably, there will be some sort of mechanism for controlling profanity filtering 
     28        which will be implemented using notifications, I imagine 
     29        */ 
     30         
     31         
     32        if (shouldFilterIncomingProfanities) { 
     33                //register for incoming and outgoing messages to filter 
     34                [[adium contentController] registerContentFilter:self 
     35                                                                                                  ofType:AIFilterContent 
     36                                                                                           direction:AIFilterIncoming]; 
     37                 
     38                [[adium contentController] registerContentFilter:self 
     39                                                                                                  ofType:AIFilterDisplay 
     40                                                                                           direction:AIFilterIncoming]; 
     41                 
     42                [[adium contentController] registerContentFilter:self 
     43                                                                                                  ofType:AIFilterMessageDisplay 
     44                                                                                           direction:AIFilterIncoming]; 
     45                 
     46                [[adium contentController] registerContentFilter:self 
     47                                                                                                  ofType:AIFilterTooltips 
     48                                                                                           direction:AIFilterIncoming]; 
     49                 
     50                [[adium contentController] registerContentFilter:self 
     51                                                                                                  ofType:AIFilterContactList 
     52                                                                                           direction:AIFilterIncoming]; 
     53                 
     54                [[adium contentController] registerContentFilter:self 
     55                                                                                                  ofType:AIFilterAutoReplyContent 
     56                                                                                           direction:AIFilterIncoming]; 
     57                 
     58                if (shouldFilterOutgoingProfanities) { 
     59                        [[adium contentController] registerContentFilter:self 
     60                                                                                                          ofType:AIFilterContent 
     61                                                                                                   direction:AIFilterOutgoing]; 
     62                         
     63                        [[adium contentController] registerContentFilter:self 
     64                                                                                                          ofType:AIFilterDisplay 
     65                                                                                                   direction:AIFilterOutgoing]; 
     66                         
     67                        [[adium contentController] registerContentFilter:self 
     68                                                                                                          ofType:AIFilterAutoReplyContent 
     69                                                                                                   direction:AIFilterOutgoing]; 
     70                } 
     71                 
     72                //should we filter profanities of all languages? 
     73                profanities = [[NSSet alloc] initWithObjects:AILocalizedString(@"shit", nil), nil]; 
     74        } 
     75} 
     76 
     77- (void)uninstallPlugin 
     78{ 
     79        if (shouldFilterIncomingProfanities || shouldFilterOutgoingProfanities) [[adium contentController] unregisterContentFilter:self]; 
     80        if (profanities) [profanities release], profanities = nil; 
     81} 
     82 
     83/*! 
     84* @brief Filter priority 
     85 * 
     86 * Filter at default priority 
     87 */ 
     88- (float)filterPriority 
     89{ 
     90        return DEFAULT_FILTER_PRIORITY; 
     91} 
     92 
     93- (NSAttributedString *)filterAttributedString:(NSAttributedString *)inAttributedString context:(id)context 
     94{ 
     95        //enumerate through all the profanities and replace all but the first letters of the profanity with dashes 
     96        NSString *textToProcess = [inAttributedString string]; 
     97        NSMutableAttributedString *text = nil; 
     98        NSEnumerator *profanityEnumerator = [profanities objectEnumerator]; 
     99        NSString *currentProfanity = nil; 
     100        NSMutableString *censoredText = nil; 
     101        int numberOfDashes = 0; 
     102        NSRange rangeOfProfanity; 
     103         
     104        //if we have anything to process (should we be processing strings that have URLs???) 
     105        if (textToProcess) { 
     106                 
     107                //censor each matching profanity 
     108                while ((currentProfanity = [profanityEnumerator nextObject])) { 
     109                         
     110                        //find the current profanity in the text 
     111                        rangeOfProfanity = [textToProcess rangeOfString:currentProfanity options:NSCaseInsensitiveSearch]; 
     112                        if (rangeOfProfanity.location != NSNotFound) { 
     113                                 
     114                                //build the replacement string 
     115                                numberOfDashes = [currentProfanity length] - 1; 
     116                                unichar firstChar = [currentProfanity characterAtIndex:0]; 
     117                                censoredText = [NSMutableString stringWithCharacters:&firstChar length:1]; 
     118                                 
     119                                for (int counter = 0; counter < numberOfDashes; counter++) { 
     120                                        [censoredText appendString:@"-"]; 
     121                                } 
     122                                 
     123                                //replace the current profanity 
     124                                if (!text) text = [[inAttributedString mutableCopy] autorelease]; 
     125                                [text replaceCharactersInRange:rangeOfProfanity withString:censoredText]; 
     126                        } 
     127                } 
     128                 
     129        } 
     130         
     131        return (text ? text : inAttributedString); 
     132} 
     133 
     134@end 
  • Resources/CoreComponents.plist

    old new  
    8383        <string>OWSpellingPerContactPlugin</string> 
    8484        <string>GBQuestionHandlerPlugin</string> 
    8585        <string>AINulRemovalPlugin</string> 
     86        <string>KGProfanityFilterPlugin</string> 
    8687</array> 
    8788</plist>