<commit_before>//
//  TopStoriesRequest.swift
//  TopStories
//
//  Created by <NAME> on 20/04/2016.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation
import CoreData

class TopStoriesRequest: NetworkRequest {
    
    var URLSession: NSURLSession?
    
    private let managedObjectContext: NSManagedObjectContext
    private let URL: NSURL
    
    init(managedObjectContext: NSManagedObjectContext, URL: NSURL) {
        self.managedObjectContext = managedObjectContext
        self.URL = URL
        
        super.init()
        self.queuePriority = .Normal
        self.qualityOfService = .UserInitiated
    }
    
    // MARK: - NSOperation
    
    override func start() {
        
        if (URLSession == nil) {
            let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
            URLSession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
        }
        
        task = URLSession?.dataTaskWithURL(URL)
        task?.resume()
    }
    
    // MARK: - NSURLSessionDataDelegate
    
    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        
        if cancelled {
            self.state = .Finished
            self.task?.cancel()
            return
        }
        
        if error != nil {
            self.error = error
            NSLog("Failed to receive response: \(error)")
            self.state = .Finished
            return
        }
        
        do {
            guard let JSONObject = try NSJSONSerialization.JSONObjectWithData(self.data,
                                                                              options: []) as? Dictionary<String, AnyObject> else {
                                                                                return;
            }
            
            let privateContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
            privateContext.parentContext = managedObjectContext
            privateContext.performBlock({
                
                // If URL exists, update the entry. If not create new entry, parse and store (using child context).
                let results = JSONObject["results"] as! [Dictionary<String, AnyObject>]
                let URLs = results.map({ $0["url"] as! String })
                // Fetch existing records at once, so there's only a single hit on the database.
                let existing = Story.instancesForContentURLs(URLs, managedObjectContext: privateContext)
                
                _ = results.map({ storyJSON in
                    
                    var story: Story
                    if let index = (existing?.map({ $0.contentURL }).indexOf({ $0 == storyJSON["url"] as? String })) {
                        story = existing![index]
                    } else {
                        story = NSEntityDescription.insertNewObjectForEntityForName(String(Story),
                            inManagedObjectContext: privateContext) as! Story
                    }
                    
                    story.abstract = storyJSON["abstract"] as? String
                    story.contentURL = storyJSON["url"] as? String
                    story.imageURL = nil // TODO: Parse imageURL
                    story.publishedDate = NSDate() // TODO: Parse published date
                    story.title = storyJSON["title"] as? String
                })
                
                // Push changes to parent context
                do {
                    try privateContext.save()
                } catch {
                    self.error = error as NSError
                    self.state = .Finished
                    return
                }
                
                // Save parent context to disk
                self.managedObjectContext.performBlock({
                    
                    do {
                        try self.managedObjectContext.save()
                    } catch {
                        self.error = error as NSError
                        self.state = .Finished
                        return
                    }
                })
            })
            
        } catch {
<commit_msg>Parse imageURL from story JSON if present<commit_after>//
//  TopStoriesRequest.swift
//  TopStories
//
//  Created by <NAME> on 20/04/2016.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation
import CoreData

class TopStoriesRequest: NetworkRequest {
    
    var URLSession: NSURLSession?
    
    private let managedObjectContext: NSManagedObjectContext
    private let URL: NSURL
    
    init(managedObjectContext: NSManagedObjectContext, URL: NSURL) {
        self.managedObjectContext = managedObjectContext
        self.URL = URL
        
        super.init()
        self.queuePriority = .Normal
        self.qualityOfService = .UserInitiated
    }
    
    // MARK: - NSOperation
    
    override func start() {
        
        if (URLSession == nil) {
            let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
            URLSession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
        }
        
        task = URLSession?.dataTaskWithURL(URL)
        task?.resume()
    }
    
    // MARK: - NSURLSessionDataDelegate
    
    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        
        if cancelled {
            self.state = .Finished
            self.task?.cancel()
            return
        }
        
        if error != nil {
            self.error = error
            NSLog("Failed to receive response: \(error)")
            self.state = .Finished
            return
        }
        
        do {
            guard let JSONObject = try NSJSONSerialization.JSONObjectWithData(self.data,
                                                                              options: []) as? Dictionary<String, AnyObject> else {
                                                                                return;
            }
            
            let privateContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
            privateContext.parentContext = managedObjectContext
            privateContext.performBlock({
                
                // If URL exists, update the entry. If not create new entry, parse and store (using child context).
                let results = JSONObject["results"] as! [Dictionary<String, AnyObject>]
                let URLs = results.map({ $0["url"] as! String })
                // Fetch existing records at once, so there's only a single hit on the database.
                let existing = Story.instancesForContentURLs(URLs, managedObjectContext: privateContext)
                
                _ = results.map({ storyJSON in
                    
                    var story: Story
                    if let index = (existing?.map({ $0.contentURL }).indexOf({ $0 == storyJSON["url"] as? String })) {
                        story = existing![index]
                    } else {
                        story = NSEntityDescription.insertNewObjectForEntityForName(String(Story),
                            inManagedObjectContext: privateContext) as! Story
                    }
                    
                    story.abstract = storyJSON["abstract"] as? String
                    story.contentURL = storyJSON["url"] as? String
                    
                    if let multimedia = storyJSON["multimedia"] as? [Dictionary<String, AnyObject>] {
                        if let index = multimedia.indexOf({ $0["format"] as? String == "thumbLarge"}) {
                            let item = multimedia[index]
                            story.imageURL = item["url"] as? String
                        }                        
                    }
                    
                    story.publishedDate = NSDate() // TODO: Parse published date
                    story.title = storyJSON["title"] as? String
                })
                
                // Push changes to parent context
                do {
                    try privateContext.save()
                } catch {
                    self.error = error as NSError
                    self.state = .Finished
                    return
                }
                
                // Save parent context to disk
                self.managedObjectContext.performBlock({
                    
                    do {
                        try self.managedObjectContext.save()
                    } catch {
                        self.error = error as NSError
                        self.state = .Finished
                        return
                    }
                })
            })
            
        } catch {

{'fraction_non_alphanumeric': 0.07538703163562935, 'fraction_numerical': 0.003477675566524568, 'mean_word_length': 1.2377008032128514, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4639378', 'n_tokens_mistral': 2042, 'n_tokens_neox': 1932, 'n_words': 513}