|
10 | 10 | #import "GLFileView.h"
|
11 | 11 | #import <CommonCrypto/CommonDigest.h>
|
12 | 12 |
|
| 13 | +@interface PBWebCommitController (Private) |
| 14 | + |
| 15 | +- (NSArray *)parseHeader:(NSString *)text; |
| 16 | +- (NSString *)htmlForHeader:(NSArray *)header withRefs:(NSString *)badges; |
| 17 | +- (NSMutableDictionary *)parseStats:(NSString *)txt; |
| 18 | +- (NSString *) arbitraryHashForString:(NSString*)concat; |
| 19 | + |
| 20 | +@end |
| 21 | + |
| 22 | + |
13 | 23 | @implementation PBWebCommitController
|
14 | 24 |
|
15 | 25 | @synthesize diff;
|
@@ -71,7 +81,8 @@ - (void)commitDetailsLoaded:(NSNotification *)notification
|
71 | 81 | return;
|
72 | 82 |
|
73 | 83 | // Header
|
74 |
| - NSString *header = [self parseHeader:details withRefs:[self refsForCurrentCommit]]; |
| 84 | + NSArray *headerItems = [self parseHeader:details]; |
| 85 | + NSString *header = [self htmlForHeader:details withRefs:[self refsForCurrentCommit]]; |
75 | 86 |
|
76 | 87 | // File Stats
|
77 | 88 | NSMutableDictionary *stats = [self parseStats:details];
|
@@ -121,60 +132,99 @@ - (NSMutableDictionary *)parseStats:(NSString *)txt
|
121 | 132 | return stats;
|
122 | 133 | }
|
123 | 134 |
|
124 |
| -- (NSString *)parseHeader:(NSString *)txt withRefs:(NSString *)badges |
| 135 | +// -parseHeader: returns an array of dictionaries with these keys |
| 136 | +const NSString *kHeaderKeyName = @"name"; |
| 137 | +const NSString *kHeaderKeyContent = @"content"; |
| 138 | + |
| 139 | +// Keys for the author/committer dictionary |
| 140 | +const NSString *kAuthorKeyName = @"name"; |
| 141 | +const NSString *kAuthorKeyEmail = @"email"; |
| 142 | +const NSString *kAuthorKeyDate = @"date"; |
| 143 | + |
| 144 | +- (NSArray *)parseHeader:(NSString *)text |
125 | 145 | {
|
126 |
| - NSArray *lines = [txt componentsSeparatedByString:@"\n"]; |
127 |
| - NSString *line; |
128 |
| - NSString *last_mail=@""; |
129 |
| - NSMutableString *auths=[NSMutableString string]; |
130 |
| - NSMutableString *refs=[NSMutableString string]; |
131 |
| - NSMutableString *subject=[NSMutableString string]; |
132 |
| - BOOL subj=FALSE; |
| 146 | + NSMutableArray *result = [NSMutableArray array]; |
| 147 | + NSArray *lines = [text componentsSeparatedByString:@"\n"]; |
| 148 | + BOOL parsingSubject = NO; |
133 | 149 |
|
134 |
| - int i; |
135 |
| - for (i=0; i<[lines count]; i++) { |
136 |
| - line=[lines objectAtIndex:i]; |
137 |
| - if([line length]==0){ |
138 |
| - if(!subj){ |
139 |
| - subj=TRUE; |
140 |
| - }else{ |
141 |
| - i=[lines count]; |
142 |
| - } |
143 |
| - }else{ |
144 |
| - if (subj) { |
145 |
| - NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
146 |
| - [subject appendString:[NSString stringWithFormat:@"%@<br/>",[GLFileView escapeHTML:trimmedLine]]]; |
147 |
| - }else{ |
148 |
| - NSArray *comps=[line componentsSeparatedByString:@" "]; |
149 |
| - if([comps count]==2){ |
150 |
| - [refs appendString:[NSString stringWithFormat:@"<tr><td>%@</td><td><a href='' onclick='selectCommit(this.innerHTML); return false;'>%@</a></td></tr>",[comps objectAtIndex:0],[comps objectAtIndex:1]]]; |
151 |
| - }else if([comps count]>2){ |
| 150 | + for (NSString *line in lines) { |
| 151 | + if ([line length] == 0) { |
| 152 | + if (!parsingSubject) |
| 153 | + parsingSubject = TRUE; |
| 154 | + else |
| 155 | + break; |
| 156 | + } else { |
| 157 | + if (parsingSubject) { |
| 158 | + NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
| 159 | + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: |
| 160 | + @"subject", kHeaderKeyName, trimmedLine, kHeaderKeyContent, nil]]; |
| 161 | + } else { |
| 162 | + NSArray *comps = [line componentsSeparatedByString:@" "]; |
| 163 | + if ([comps count] == 2) { |
| 164 | + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: |
| 165 | + [comps objectAtIndex:0], kHeaderKeyName, |
| 166 | + [comps objectAtIndex:1], kHeaderKeyContent, nil]]; |
| 167 | + } else if ([comps count] > 2) { |
152 | 168 | NSRange r_email_i = [line rangeOfString:@"<"];
|
153 | 169 | NSRange r_email_e = [line rangeOfString:@">"];
|
154 | 170 | NSRange r_name_i = [line rangeOfString:@" "];
|
155 | 171 |
|
156 |
| - NSString *rol=[line substringToIndex:r_name_i.location]; |
157 |
| - NSString *name=[line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; |
158 |
| - NSString *email=[line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; |
| 172 | + NSString *name = [line substringWithRange:NSMakeRange(r_name_i.location,(r_email_i.location-r_name_i.location))]; |
| 173 | + NSString *email = [line substringWithRange:NSMakeRange(r_email_i.location+1,((r_email_e.location-1)-r_email_i.location))]; |
159 | 174 |
|
160 | 175 | NSArray *t=[[line substringFromIndex:r_email_e.location+2] componentsSeparatedByString:@" "];
|
161 | 176 | NSDate *date=[NSDate dateWithTimeIntervalSince1970:[[t objectAtIndex:0] doubleValue]];
|
| 177 | + |
| 178 | + [result addObject:[NSDictionary dictionaryWithObjectsAndKeys: |
| 179 | + [comps objectAtIndex:0], kHeaderKeyName, |
| 180 | + [NSDictionary dictionaryWithObjectsAndKeys: |
| 181 | + name, kAuthorKeyName, |
| 182 | + email, kAuthorKeyEmail, |
| 183 | + date, kAuthorKeyDate, |
| 184 | + nil], |
| 185 | + nil]]; |
| 186 | + } |
| 187 | + } |
| 188 | + } |
| 189 | + } |
| 190 | + |
| 191 | + return result; |
| 192 | +} |
| 193 | + |
| 194 | +- (NSString *)htmlForHeader:(NSArray *)header withRefs:(NSString *)badges |
| 195 | +{ |
| 196 | + NSString *last_mail = @""; |
| 197 | + NSMutableString *auths=[NSMutableString string]; |
| 198 | + NSMutableString *refs=[NSMutableString string]; |
| 199 | + NSMutableString *subject=[NSMutableString string]; |
| 200 | + |
| 201 | + for (NSDictionary *item in header) { |
| 202 | + if ([[item objectForKey:kHeaderKeyName] isEqualToString:@"subject"]) { |
| 203 | + [subject appendString:[NSString stringWithFormat:@"%@<br/>",[GLFileView escapeHTML:[item objectForKey:kHeaderKeyContent]]]]; |
| 204 | + }else{ |
| 205 | + if([[item objectForKey:kHeaderKeyContent] isKindOfClass:[NSString class]]){ |
| 206 | + [refs appendString:[NSString stringWithFormat:@"<tr><td>%@</td><td><a href='' onclick='selectCommit(this.innerHTML); return false;'>%@</a></td></tr>",[item objectForKey:kHeaderKeyName],[item objectForKey:kHeaderKeyContent]]]; |
| 207 | + }else{ // NSDictionary: author or committer |
| 208 | + NSDictionary *content = [item objectForKey:kHeaderKeyContent]; |
| 209 | + NSString *email = [content objectForKey:kAuthorKeyEmail]; |
| 210 | + |
| 211 | + if(![email isEqualToString:last_mail]){ |
| 212 | + NSString *name = [content objectForKey:kAuthorKeyName]; |
| 213 | + NSDate *date = [content objectForKey:kAuthorKeyDate]; |
162 | 214 | NSDateFormatter* theDateFormatter = [[NSDateFormatter alloc] init];
|
163 | 215 | [theDateFormatter setDateStyle:NSDateFormatterMediumStyle];
|
164 | 216 | [theDateFormatter setTimeStyle:NSDateFormatterMediumStyle];
|
165 | 217 | NSString *dateString=[theDateFormatter stringForObjectValue:date];
|
166 |
| - |
167 |
| - if(![email isEqualToString:last_mail]){ |
168 |
| - [auths appendString:[NSString stringWithFormat:@"<div class='user %@ clearfix'>",rol]]; |
169 |
| - if([self isFeatureEnabled:@"gravatar"]){ |
170 |
| - NSString *hash=[self arbitraryHashForString:email]; |
171 |
| - [auths appendString:[NSString stringWithFormat:@"<img class='avatar' src='http://www.gravatar.com/avatar/%@?d=wavatar&s=30'/>",hash]]; |
172 |
| - } |
173 |
| - [auths appendString:[NSString stringWithFormat:@"<p class='name'>%@ <span class='rol'>(%@)</span></p>",name,rol]]; |
174 |
| - [auths appendString:[NSString stringWithFormat:@"<p class='time'>%@</p></div>",dateString]]; |
| 218 | + |
| 219 | + [auths appendString:[NSString stringWithFormat:@"<div class='user %@ clearfix'>",rol]]; |
| 220 | + if([self isFeatureEnabled:@"gravatar"]){ |
| 221 | + NSString *hash=[self arbitraryHashForString:email]; |
| 222 | + [auths appendString:[NSString stringWithFormat:@"<img class='avatar' src='http://www.gravatar.com/avatar/%@?d=wavatar&s=30'/>",hash]]; |
175 | 223 | }
|
176 |
| - last_mail=email; |
| 224 | + [auths appendString:[NSString stringWithFormat:@"<p class='name'>%@ <span class='rol'>(%@)</span></p>",name,rol]]; |
| 225 | + [auths appendString:[NSString stringWithFormat:@"<p class='time'>%@</p></div>",dateString]]; |
177 | 226 | }
|
| 227 | + last_mail=email; |
178 | 228 | }
|
179 | 229 | }
|
180 | 230 | }
|
|
0 commit comments