public HttpResponseMessage UploadReport(long timestamp)
        {
            DicServerContext ctx = new DicServerContext();

            SyncDto  sync     = new SyncDto();
            DateTime lastSync = DateHandlers.UnixToDateTime(timestamp);

            sync.UsbVendors = new List <UsbVendorDto>();
            foreach (UsbVendor vendor in ctx.UsbVendors.Where(v => v.ModifiedWhen > lastSync))
            {
                sync.UsbVendors.Add(new UsbVendorDto {
                    VendorId = (ushort)vendor.VendorId, Vendor = vendor.Vendor
                });
            }

            sync.UsbProducts = new List <UsbProductDto>();
            foreach (UsbProduct product in ctx.UsbProducts.Where(p => p.ModifiedWhen > lastSync))
            {
                sync.UsbProducts.Add(new UsbProductDto
                {
                    Id        = product.Id,
                    Product   = product.Product,
                    ProductId = (ushort)product.ProductId,
                    VendorId  = (ushort)product.Vendor.VendorId
                });
            }

            sync.Offsets = new List <CdOffsetDto>();
            foreach (CompactDiscOffset offset in ctx.CdOffsets.Where(o => o.ModifiedWhen > lastSync))
            {
                sync.Offsets.Add(new CdOffsetDto(offset, offset.Id));
            }

            sync.Devices = new List <DeviceDto>();
            foreach (Device device in ctx.Devices.Where(d => d.ModifiedWhen > lastSync).ToList())
            {
                sync.Devices.Add(new
                                 DeviceDto(JsonConvert.DeserializeObject <DeviceReportV2>(JsonConvert.SerializeObject(device, Formatting.None, new JsonSerializerSettings {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                })),
                                           device.Id, device.OptimalMultipleSectorsRead));
            }

            JsonSerializer js = JsonSerializer.Create();
            StringWriter   sw = new StringWriter();

            js.Serialize(sw, sync);

            return(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent(sw.ToString(), Encoding.UTF8, "application/json")
            });
        }
        public ActionResult View(int?id)
        {
            if (id == null || id <= 0)
            {
                return(Content("Incorrect device report request"));
            }

            try
            {
                DicServerContext ctx    = new DicServerContext();
                Device           report = ctx.Devices.FirstOrDefault(d => d.Id == id);

                if (report is null)
                {
                    return(Content("Cannot find requested report"));
                }

                ViewBag.lblManufacturer = report.Manufacturer;
                ViewBag.lblModel        = report.Model;
                ViewBag.lblRevision     = report.Revision;

                if (report.USB != null)
                {
                    string usbVendorDescription  = null;
                    string usbProductDescription = null;

                    UsbProduct dbProduct =
                        ctx.UsbProducts.FirstOrDefault(p => p.ProductId == report.USB.ProductID &&
                                                       p.Vendor != null &&
                                                       p.Vendor.VendorId == report.USB.VendorID);

                    if (dbProduct is null)
                    {
                        UsbVendor dbVendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == report.USB.VendorID);

                        if (!(dbVendor is null))
                        {
                            usbVendorDescription = dbVendor.Vendor;
                        }
                    }
                    else
                    {
                        usbProductDescription = dbProduct.Product;
                        usbVendorDescription  = dbProduct.Vendor.Vendor;
                    }

                    ViewBag.UsbItem = new Item
                    {
                        Manufacturer      = report.USB.Manufacturer,
                        Product           = report.USB.Product,
                        VendorDescription =
                            usbVendorDescription != null
                                ? $"0x{report.USB.VendorID:x4} ({usbVendorDescription})"
                                : $"0x{report.USB.VendorID:x4}",
                        ProductDescription = usbProductDescription != null
                                                 ? $"0x{report.USB.ProductID:x4} ({usbProductDescription})"
                                                 : $"0x{report.USB.ProductID:x4}"
                    };
                }

                if (report.FireWire != null)
                {
                    ViewBag.FireWireItem = new Item
                    {
                        Manufacturer       = report.FireWire.Manufacturer,
                        Product            = report.FireWire.Product,
                        VendorDescription  = $"0x{report.FireWire.VendorID:x8}",
                        ProductDescription = $"0x{report.FireWire.ProductID:x8}"
                    }
                }
                ;

                if (report.PCMCIA != null)
                {
                    ViewBag.PcmciaItem = new PcmciaItem
                    {
                        Manufacturer       = report.PCMCIA.Manufacturer,
                        Product            = report.PCMCIA.ProductName,
                        VendorDescription  = $"0x{report.PCMCIA.ManufacturerCode:x4}",
                        ProductDescription = $"0x{report.PCMCIA.CardCode:x4}",
                        Compliance         = report.PCMCIA.Compliance
                    };

                    Tuple[] tuples = CIS.GetTuples(report.PCMCIA.CIS);
                    if (tuples != null)
                    {
                        Dictionary <string, string> decodedTuples = new Dictionary <string, string>();
                        foreach (Tuple tuple in tuples)
                        {
                            switch (tuple.Code)
                            {
                            case TupleCodes.CISTPL_NULL:
                            case TupleCodes.CISTPL_END:
                            case TupleCodes.CISTPL_MANFID:
                            case TupleCodes.CISTPL_VERS_1: break;

                            case TupleCodes.CISTPL_DEVICEGEO:
                            case TupleCodes.CISTPL_DEVICEGEO_A:
                                DeviceGeometryTuple geom = CIS.DecodeDeviceGeometryTuple(tuple.Data);
                                if (geom?.Geometries != null)
                                {
                                    foreach (DeviceGeometry geometry in geom.Geometries)
                                    {
                                        decodedTuples.Add("Device width",
                                                          $"{(1 << (geometry.CardInterface - 1)) * 8} bits");
                                        decodedTuples.Add("Erase block",
                                                          $"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
                                        decodedTuples.Add("Read block",
                                                          $"{(1 << (geometry.ReadBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
                                        decodedTuples.Add("Write block",
                                                          $"{(1 << (geometry.WriteBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
                                        decodedTuples.Add("Partition alignment",
                                                          $"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1)) * (1 << (geometry.Partitions - 1))} bytes");
                                    }
                                }

                                break;

                            case TupleCodes.CISTPL_ALTSTR:
                            case TupleCodes.CISTPL_BAR:
                            case TupleCodes.CISTPL_BATTERY:
                            case TupleCodes.CISTPL_BYTEORDER:
                            case TupleCodes.CISTPL_CFTABLE_ENTRY:
                            case TupleCodes.CISTPL_CFTABLE_ENTRY_CB:
                            case TupleCodes.CISTPL_CHECKSUM:
                            case TupleCodes.CISTPL_CONFIG:
                            case TupleCodes.CISTPL_CONFIG_CB:
                            case TupleCodes.CISTPL_DATE:
                            case TupleCodes.CISTPL_DEVICE:
                            case TupleCodes.CISTPL_DEVICE_A:
                            case TupleCodes.CISTPL_DEVICE_OA:
                            case TupleCodes.CISTPL_DEVICE_OC:
                            case TupleCodes.CISTPL_EXTDEVIC:
                            case TupleCodes.CISTPL_FORMAT:
                            case TupleCodes.CISTPL_FORMAT_A:
                            case TupleCodes.CISTPL_FUNCE:
                            case TupleCodes.CISTPL_FUNCID:
                            case TupleCodes.CISTPL_GEOMETRY:
                            case TupleCodes.CISTPL_INDIRECT:
                            case TupleCodes.CISTPL_JEDEC_A:
                            case TupleCodes.CISTPL_JEDEC_C:
                            case TupleCodes.CISTPL_LINKTARGET:
                            case TupleCodes.CISTPL_LONGLINK_A:
                            case TupleCodes.CISTPL_LONGLINK_C:
                            case TupleCodes.CISTPL_LONGLINK_CB:
                            case TupleCodes.CISTPL_LONGLINK_MFC:
                            case TupleCodes.CISTPL_NO_LINK:
                            case TupleCodes.CISTPL_ORG:
                            case TupleCodes.CISTPL_PWR_MGMNT:
                            case TupleCodes.CISTPL_SPCL:
                            case TupleCodes.CISTPL_SWIL:
                            case TupleCodes.CISTPL_VERS_2:
                                decodedTuples.Add("Undecoded tuple ID", tuple.Code.ToString());
                                break;

                            default:
                                decodedTuples.Add("Unknown tuple ID", $"0x{(byte)tuple.Code:X2}");
                                break;
                            }
                        }

                        if (decodedTuples.Count > 0)
                        {
                            ViewBag.repPcmciaTuples = decodedTuples;
                        }
                    }
                }

                bool removable = true;
                List <TestedMedia> testedMedia = null;
                bool ata      = false;
                bool atapi    = false;
                bool sscMedia = false;

                if (report.ATA != null || report.ATAPI != null)
                {
                    ata = true;
                    List <string> ataOneValue = new List <string>();
                    Dictionary <string, string> ataTwoValue = new Dictionary <string, string>();
                    CommonTypes.Metadata.Ata    ataReport;

                    if (report.ATAPI != null)
                    {
                        ViewBag.AtaItem = "ATAPI";
                        ataReport       = report.ATAPI;
                        atapi           = true;
                    }
                    else
                    {
                        ViewBag.AtaItem = "ATA";
                        ataReport       = report.ATA;
                    }

                    bool cfa = report.CompactFlash;

                    if (atapi && !cfa)
                    {
                        ViewBag.lblAtaDeviceType = "ATAPI device";
                    }
                    else if (!atapi && cfa)
                    {
                        ViewBag.lblAtaDeviceType = "CompactFlash device";
                    }
                    else
                    {
                        ViewBag.lblAtaDeviceType = "ATA device";
                    }

                    Ata.Report(ataReport, cfa, atapi, ref removable, ref ataOneValue, ref ataTwoValue, ref testedMedia);

                    ViewBag.repAtaOne = ataOneValue;
                    ViewBag.repAtaTwo = ataTwoValue;
                }

                if (report.SCSI != null)
                {
                    List <string> scsiOneValue            = new List <string>();
                    Dictionary <string, string> modePages = new Dictionary <string, string>();
                    Dictionary <string, string> evpdPages = new Dictionary <string, string>();

                    string vendorId = StringHandlers.CToString(report.SCSI.Inquiry?.VendorIdentification);
                    if (report.SCSI.Inquiry != null)
                    {
                        Inquiry.SCSIInquiry inq = report.SCSI.Inquiry.Value;
                        ViewBag.lblScsiVendor = VendorString.Prettify(vendorId) != vendorId
                                                    ? $"{vendorId} ({VendorString.Prettify(vendorId)})"
                                                    : vendorId;
                        ViewBag.lblScsiProduct  = StringHandlers.CToString(inq.ProductIdentification);
                        ViewBag.lblScsiRevision = StringHandlers.CToString(inq.ProductRevisionLevel);
                    }

                    scsiOneValue.AddRange(ScsiInquiry.Report(report.SCSI.Inquiry));

                    if (report.SCSI.SupportsModeSense6)
                    {
                        scsiOneValue.Add("Device supports MODE SENSE (6)");
                    }
                    if (report.SCSI.SupportsModeSense10)
                    {
                        scsiOneValue.Add("Device supports MODE SENSE (10)");
                    }
                    if (report.SCSI.SupportsModeSubpages)
                    {
                        scsiOneValue.Add("Device supports MODE SENSE subpages");
                    }

                    if (report.SCSI.ModeSense != null)
                    {
                        PeripheralDeviceTypes devType = PeripheralDeviceTypes.DirectAccess;
                        if (report.SCSI.Inquiry != null)
                        {
                            devType = (PeripheralDeviceTypes)report.SCSI.Inquiry.Value.PeripheralDeviceType;
                        }
                        ScsiModeSense.Report(report.SCSI.ModeSense, vendorId, devType, ref scsiOneValue, ref modePages);
                    }

                    if (modePages.Count > 0)
                    {
                        ViewBag.repModeSense = modePages;
                    }

                    if (report.SCSI.EVPDPages != null)
                    {
                        ScsiEvpd.Report(report.SCSI.EVPDPages, vendorId, ref evpdPages);
                    }

                    if (evpdPages.Count > 0)
                    {
                        ViewBag.repEvpd = evpdPages;
                    }

                    if (report.SCSI.MultiMediaDevice != null)
                    {
                        testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;

                        if (report.SCSI.MultiMediaDevice.ModeSense2A != null)
                        {
                            List <string> mmcModeOneValue = new List <string>();
                            ScsiMmcMode.Report(report.SCSI.MultiMediaDevice.ModeSense2A, ref mmcModeOneValue);
                            if (mmcModeOneValue.Count > 0)
                            {
                                ViewBag.repScsiMmcMode = mmcModeOneValue;
                            }
                        }

                        if (report.SCSI.MultiMediaDevice.Features != null)
                        {
                            List <string> mmcFeaturesOneValue = new List <string>();
                            ScsiMmcFeatures.Report(report.SCSI.MultiMediaDevice.Features, ref mmcFeaturesOneValue);
                            if (mmcFeaturesOneValue.Count > 0)
                            {
                                ViewBag.repScsiMmcFeatures = mmcFeaturesOneValue;
                            }
                        }
                    }
                    else if (report.SCSI.SequentialDevice != null)
                    {
                        ViewBag.divScsiSscVisible = true;

                        ViewBag.lblScsiSscGranularity =
                            report.SCSI.SequentialDevice.BlockSizeGranularity?.ToString() ?? "Unspecified";

                        ViewBag.lblScsiSscMaxBlock =
                            report.SCSI.SequentialDevice.MaxBlockLength?.ToString() ?? "Unspecified";

                        ViewBag.lblScsiSscMinBlock =
                            report.SCSI.SequentialDevice.MinBlockLength?.ToString() ?? "Unspecified";

                        if (report.SCSI.SequentialDevice.SupportedDensities != null)
                        {
                            ViewBag.repScsiSscDensities = report.SCSI.SequentialDevice.SupportedDensities;
                        }

                        if (report.SCSI.SequentialDevice.SupportedMediaTypes != null)
                        {
                            ViewBag.repScsiSscMedias = report.SCSI.SequentialDevice.SupportedMediaTypes;
                        }

                        if (report.SCSI.SequentialDevice.TestedMedia != null)
                        {
                            List <string> mediaOneValue = new List <string>();
                            SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue);
                            if (mediaOneValue.Count > 0)
                            {
                                sscMedia = true;
                                ViewBag.repTestedMedia = mediaOneValue;
                            }
                        }
                    }
                    else if (report.SCSI.ReadCapabilities != null)
                    {
                        removable = false;
                        scsiOneValue.Add("");

                        if (report.SCSI.ReadCapabilities.Blocks.HasValue &&
                            report.SCSI.ReadCapabilities.BlockSize.HasValue)
                        {
                            scsiOneValue
                            .Add($"Device has {report.SCSI.ReadCapabilities.Blocks} blocks of {report.SCSI.ReadCapabilities.BlockSize} bytes each");

                            if (report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 /
                                1024 > 1000000)
                            {
                                scsiOneValue
                                .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
                            }
                            else if (report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize /
                                     1024 /
                                     1024 > 1000)
                            {
                                scsiOneValue
                                .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
                            }
                            else
                            {
                                scsiOneValue
                                .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000} Mb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024:F2} MiB");
                            }
                        }

                        if (report.SCSI.ReadCapabilities.MediumType.HasValue)
                        {
                            scsiOneValue.Add($"Medium type code: {report.SCSI.ReadCapabilities.MediumType:X2}h");
                        }
                        if (report.SCSI.ReadCapabilities.Density.HasValue)
                        {
                            scsiOneValue.Add($"Density code: {report.SCSI.ReadCapabilities.Density:X2}h");
                        }
                        if ((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
                             report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
                            report.SCSI.ReadCapabilities.LongBlockSize.HasValue)
                        {
                            scsiOneValue.Add($"Long block size: {report.SCSI.ReadCapabilities.LongBlockSize} bytes");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsReadCapacity == true)
                        {
                            scsiOneValue.Add("Device supports READ CAPACITY (10) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsReadCapacity16 == true)
                        {
                            scsiOneValue.Add("Device supports READ CAPACITY (16) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsRead6 == true)
                        {
                            scsiOneValue.Add("Device supports READ (6) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsRead10 == true)
                        {
                            scsiOneValue.Add("Device supports READ (10) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsRead12 == true)
                        {
                            scsiOneValue.Add("Device supports READ (12) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsRead16 == true)
                        {
                            scsiOneValue.Add("Device supports READ (16) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsReadLong == true)
                        {
                            scsiOneValue.Add("Device supports READ LONG (10) command.");
                        }
                        if (report.SCSI.ReadCapabilities.SupportsReadLong16 == true)
                        {
                            scsiOneValue.Add("Device supports READ LONG (16) command.");
                        }
                    }
                    else
                    {
                        testedMedia = report.SCSI.RemovableMedias;
                    }

                    ViewBag.repScsi = scsiOneValue;
                }

                if (report.MultiMediaCard != null)
                {
                    List <string> mmcOneValue = new List <string>();

                    if (report.MultiMediaCard.CID != null)
                    {
                        mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID)
                                        .Replace("\n", "<br/>"));
                        mmcOneValue.Add("");
                    }

                    if (report.MultiMediaCard.CSD != null)
                    {
                        mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.CSD)
                                        .Replace("\n", "<br/>"));
                        mmcOneValue.Add("");
                    }

                    if (report.MultiMediaCard.ExtendedCSD != null)
                    {
                        mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyExtendedCSD(report.MultiMediaCard.ExtendedCSD)
                                        .Replace("\n", "<br/>"));
                        mmcOneValue.Add("");
                    }

                    if (report.MultiMediaCard.OCR != null)
                    {
                        mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.OCR)
                                        .Replace("\n", "<br/>"));
                        mmcOneValue.Add("");
                    }

                    ViewBag.repMMC = mmcOneValue;
                }

                if (report.SecureDigital != null)
                {
                    List <string> sdOneValue = new List <string>();

                    if (report.SecureDigital.CID != null)
                    {
                        sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID)
                                       .Replace("\n", "<br/>"));
                        sdOneValue.Add("");
                    }

                    if (report.SecureDigital.CSD != null)
                    {
                        sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.CSD)
                                       .Replace("\n", "<br/>"));
                        sdOneValue.Add("");
                    }

                    if (report.SecureDigital.SCR != null)
                    {
                        sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifySCR(report.SecureDigital.SCR)
                                       .Replace("\n", "<br/>"));
                        sdOneValue.Add("");
                    }

                    if (report.SecureDigital.OCR != null)
                    {
                        sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR)
                                       .Replace("\n", "<br/>"));
                        sdOneValue.Add("");
                    }

                    ViewBag.repSD = sdOneValue;
                }

                if (removable && !sscMedia && testedMedia != null)
                {
                    List <string> mediaOneValue = new List <string>();
                    App_Start.TestedMedia.Report(testedMedia, ref mediaOneValue);
                    if (mediaOneValue.Count > 0)
                    {
                        ViewBag.repTestedMedia = mediaOneValue;
                    }
                }
            }
            catch (Exception)
            {
                #if DEBUG
                throw;
                #endif
                return(Content("Could not load device report"));
            }

            return(View());
        }
Esempio n. 3
0
 public UploadStatsController(IWebHostEnvironment environment, DicServerContext ctx)
 {
     _environment = environment;
     _ctx         = ctx;
 }
 public UpdateController(DicServerContext ctx) => _ctx = ctx;
Esempio n. 5
0
        public static void Main(string[] args)
        {
            DateTime start, end;

            start = DateTime.UtcNow;
            System.Console.WriteLine("{0}: Connecting to database...", DateTime.UtcNow);
            var ctx = new DicServerContext();

            end = DateTime.UtcNow;
            System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

            System.Console.WriteLine("{0}: Migrating database to latest version...", DateTime.UtcNow);
            start = DateTime.UtcNow;
            ctx.Database.Migrate();
            end = DateTime.UtcNow;
            System.Console.WriteLine("{0}: Took {1:F2} seconds", DateTime.UtcNow, (end - start).TotalSeconds);

            WebClient client;

            try
            {
                System.Console.WriteLine("{0}: Retrieving USB IDs from Linux USB...", DateTime.UtcNow);
                start  = DateTime.UtcNow;
                client = new WebClient();
                var sr = new StringReader(client.DownloadString("http://www.linux-usb.org/usb.ids"));
                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                UsbVendor vendor           = null;
                int       newVendors       = 0;
                int       newProducts      = 0;
                int       modifiedVendors  = 0;
                int       modifiedProducts = 0;
                int       counter          = 0;

                start = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Adding and updating database entries...", DateTime.UtcNow);

                do
                {
                    if (counter == 1000)
                    {
                        DateTime start2 = DateTime.UtcNow;
                        System.Console.WriteLine("{0}: Saving changes", start2);
                        ctx.SaveChanges();
                        end = DateTime.UtcNow;
                        System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start2).TotalSeconds);
                        counter = 0;
                    }

                    string line = sr.ReadLine();

                    if (line is null)
                    {
                        break;
                    }

                    if (line.Length == 0 ||
                        line[0] == '#')
                    {
                        continue;
                    }

                    ushort number;
                    string name;

                    if (line[0] == '\t')
                    {
                        try
                        {
                            number = Convert.ToUInt16(line.Substring(1, 4), 16);
                        }
                        catch (FormatException)
                        {
                            continue;
                        }

                        if (number == 0)
                        {
                            continue;
                        }

                        name = line.Substring(7);

                        UsbProduct product =
                            ctx.UsbProducts.FirstOrDefault(p => p.ProductId == number && p.Vendor != null &&
                                                           p.Vendor.VendorId == vendor.VendorId);

                        if (product is null)
                        {
                            product = new UsbProduct(vendor, number, name);
                            ctx.UsbProducts.Add(product);

                            System.Console.WriteLine("{0}: Will add product {1} with ID {2:X4} and vendor {3} ({4:X4})",
                                                     DateTime.UtcNow, product.Product, product.ProductId,
                                                     product.Vendor?.Vendor ?? "null", product.Vendor?.VendorId ?? 0);

                            newProducts++;
                            counter++;
                        }
                        else if (name != product.Product)
                        {
                            System.Console.
                            WriteLine("{0}: Will modify product with ID {1:X4} and vendor {2} ({3:X4}) from \"{4}\" to \"{5}\"",
                                      DateTime.UtcNow, product.ProductId, product.Vendor?.Vendor ?? "null",
                                      product.Vendor?.VendorId ?? 0,
                                      product.Product, name);

                            product.Product      = name;
                            product.ModifiedWhen = DateTime.UtcNow;
                            modifiedProducts++;
                            counter++;
                        }

                        continue;
                    }

                    try
                    {
                        number = Convert.ToUInt16(line.Substring(0, 4), 16);
                    }
                    catch (FormatException)
                    {
                        continue;
                    }

                    if (number == 0)
                    {
                        continue;
                    }

                    name = line.Substring(6);

                    vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == number);

                    if (vendor is null)
                    {
                        vendor = new UsbVendor(number, name);
                        ctx.UsbVendors.Add(vendor);

                        System.Console.WriteLine("{0}: Will add vendor {1} with ID {2:X4}", DateTime.UtcNow,
                                                 vendor.Vendor, vendor.VendorId);

                        newVendors++;
                        counter++;
                    }
                    else if (name != vendor.Vendor)
                    {
                        System.Console.WriteLine("{0}: Will modify vendor with ID {1:X4} from \"{2}\" to \"{3}\"",
                                                 DateTime.UtcNow, vendor.VendorId, vendor.Vendor, name);

                        vendor.Vendor       = name;
                        vendor.ModifiedWhen = DateTime.UtcNow;
                        modifiedVendors++;
                        counter++;
                    }
                } while(true);

                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                System.Console.WriteLine("{0}: Saving database changes...", DateTime.UtcNow);
                start = DateTime.UtcNow;
                ctx.SaveChanges();
                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                System.Console.WriteLine("{0}: {1} vendors added.", DateTime.UtcNow, newVendors);
                System.Console.WriteLine("{0}: {1} products added.", DateTime.UtcNow, newProducts);
                System.Console.WriteLine("{0}: {1} vendors modified.", DateTime.UtcNow, modifiedVendors);
                System.Console.WriteLine("{0}: {1} products modified.", DateTime.UtcNow, modifiedProducts);

                System.Console.WriteLine("{0}: Looking up a vendor", DateTime.UtcNow);
                start  = DateTime.UtcNow;
                vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == 0x8086);

                if (vendor is null)
                {
                    System.Console.WriteLine("{0}: Error, could not find vendor.", DateTime.UtcNow);
                }
                else
                {
                    System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, vendor.Vendor);
                }

                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                System.Console.WriteLine("{0}: Looking up a product", DateTime.UtcNow);
                start = DateTime.UtcNow;

                UsbProduct prd =
                    ctx.UsbProducts.FirstOrDefault(p => p.ProductId == 0x0001 && p.Vendor.VendorId == 0x8086);

                if (prd is null)
                {
                    System.Console.WriteLine("{0}: Error, could not find product.", DateTime.UtcNow);
                }
                else
                {
                    System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, prd.Product);
                }

                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
            }
            catch (Exception ex)
            {
            #if DEBUG
                if (Debugger.IsAttached)
                {
                    throw;
                }
            #endif
                System.Console.WriteLine("{0}: Exception {1} filling USB IDs...", DateTime.UtcNow, ex);
            }

            System.Console.WriteLine("{0}: Fixing all devices without modification time...", DateTime.UtcNow);
            start = DateTime.UtcNow;

            foreach (Device device in ctx.Devices.Where(d => d.ModifiedWhen == null))
            {
                device.ModifiedWhen = device.AddedWhen;
            }

            end = DateTime.UtcNow;
            System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

            System.Console.WriteLine("{0}: Committing changes...", DateTime.UtcNow);
            start = DateTime.UtcNow;
            ctx.SaveChanges();
            end = DateTime.UtcNow;
            System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

            try
            {
                System.Console.WriteLine("{0}: Retrieving CompactDisc read offsets from AccurateRip...",
                                         DateTime.UtcNow);

                start = DateTime.UtcNow;

                client = new WebClient();
                string html = client.DownloadString("http://www.accuraterip.com/driveoffsets.htm");
                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                // The HTML is too malformed to process easily, so find start of table
                html = "<html><body><table><tr>" +
                       html.Substring(html.IndexOf("<td bgcolor=\"#000000\">", StringComparison.Ordinal));

                var doc = new HtmlDocument();
                doc.LoadHtml(html);
                HtmlNode firstTable = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/table[1]");

                bool firstRow = true;

                int addedOffsets    = 0;
                int modifiedOffsets = 0;

                System.Console.WriteLine("{0}: Processing offsets...", DateTime.UtcNow);
                start = DateTime.UtcNow;

                foreach (HtmlNode row in firstTable.Descendants("tr"))
                {
                    HtmlNode[] columns = row.Descendants("td").ToArray();

                    if (columns.Length != 4)
                    {
                        System.Console.WriteLine("{0}: Row does not have correct number of columns...",
                                                 DateTime.UtcNow);

                        continue;
                    }

                    string column0 = columns[0].InnerText;
                    string column1 = columns[1].InnerText;
                    string column2 = columns[2].InnerText;
                    string column3 = columns[3].InnerText;

                    if (firstRow)
                    {
                        if (column0.ToLowerInvariant() != "cd drive")
                        {
                            System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
                                                     columns[0].InnerText);

                            break;
                        }

                        if (column1.ToLowerInvariant() != "correction offset")
                        {
                            System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
                                                     columns[1].InnerText);

                            break;
                        }

                        if (column2.ToLowerInvariant() != "submitted by")
                        {
                            System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
                                                     columns[2].InnerText);

                            break;
                        }

                        if (column3.ToLowerInvariant() != "percentage agree")
                        {
                            System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
                                                     columns[3].InnerText);

                            break;
                        }

                        firstRow = false;

                        continue;
                    }

                    string manufacturer;
                    string model;

                    if (column0[0] == '-' &&
                        column0[1] == ' ')
                    {
                        manufacturer = null;
                        model        = column0.Substring(2).Trim();
                    }
                    else
                    {
                        int cutOffset = column0.IndexOf(" - ", StringComparison.Ordinal);

                        if (cutOffset == -1)
                        {
                            manufacturer = null;
                            model        = column0;
                        }
                        else
                        {
                            manufacturer = column0.Substring(0, cutOffset).Trim();
                            model        = column0.Substring(cutOffset + 3).Trim();
                        }
                    }

                    switch (manufacturer)
                    {
                    case "Lite-ON":
                        manufacturer = "JLMS";

                        break;

                    case "LG Electronics":
                        manufacturer = "HL-DT-ST";

                        break;

                    case "Panasonic":
                        manufacturer = "MATSHITA";

                        break;
                    }

                    CompactDiscOffset cdOffset =
                        ctx.CdOffsets.FirstOrDefault(o => o.Manufacturer == manufacturer && o.Model == model);

                    if (column1.ToLowerInvariant() == "[purged]")
                    {
                        if (cdOffset != null)
                        {
                            ctx.CdOffsets.Remove(cdOffset);
                        }

                        continue;
                    }

                    if (!short.TryParse(column1, out short offset))
                    {
                        continue;
                    }

                    if (!int.TryParse(column2, out int submissions))
                    {
                        continue;
                    }

                    if (column3[column3.Length - 1] != '%')
                    {
                        continue;
                    }

                    column3 = column3.Substring(0, column3.Length - 1);

                    if (!float.TryParse(column3, out float percentage))
                    {
                        continue;
                    }

                    percentage /= 100;

                    if (cdOffset is null)
                    {
                        cdOffset = new CompactDiscOffset
                        {
                            AddedWhen    = DateTime.UtcNow, ModifiedWhen = DateTime.UtcNow, Agreement = percentage,
                            Manufacturer = manufacturer, Model = model, Offset = offset,
                            Submissions  = submissions
                        };

                        ctx.CdOffsets.Add(cdOffset);
                        addedOffsets++;
                    }
                    else
                    {
                        if (Math.Abs(cdOffset.Agreement - percentage) > 0)
                        {
                            cdOffset.Agreement    = percentage;
                            cdOffset.ModifiedWhen = DateTime.UtcNow;
                        }

                        if (cdOffset.Offset != offset)
                        {
                            cdOffset.Offset       = offset;
                            cdOffset.ModifiedWhen = DateTime.UtcNow;
                        }

                        if (cdOffset.Submissions != submissions)
                        {
                            cdOffset.Submissions  = submissions;
                            cdOffset.ModifiedWhen = DateTime.UtcNow;
                        }

                        if (Math.Abs(cdOffset.Agreement - percentage) > 0 ||
                            cdOffset.Offset != offset ||
                            cdOffset.Submissions != submissions)
                        {
                            modifiedOffsets++;
                        }
                    }

                    foreach (Device device in ctx.
                             Devices.
                             Where(d => d.Manufacturer == null && d.Model != null &&
                                   d.Model.Trim() == model).
                             Union(ctx.Devices.Where(d => d.Manufacturer != null &&
                                                     d.Manufacturer.Trim() == manufacturer &&
                                                     d.Model != null &&
                                                     d.Model == model)))
                    {
                        if (device.CdOffset == cdOffset &&
                            device.ModifiedWhen == cdOffset.ModifiedWhen)
                        {
                            continue;
                        }

                        device.CdOffset     = cdOffset;
                        device.ModifiedWhen = cdOffset.ModifiedWhen;
                    }
                }

                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                System.Console.WriteLine("{0}: Committing changes...", DateTime.UtcNow);
                start = DateTime.UtcNow;
                ctx.SaveChanges();
                end = DateTime.UtcNow;
                System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);

                System.Console.WriteLine("{0}: Added {1} offsets", end, addedOffsets);
                System.Console.WriteLine("{0}: Modified {1} offsets", end, modifiedOffsets);
            }
            catch (Exception ex)
            {
            #if DEBUG
                if (Debugger.IsAttached)
                {
                    throw;
                }
            #endif
                System.Console.WriteLine("{0}: Exception {1} filling CompactDisc read offsets...", DateTime.UtcNow, ex);
            }
        }
 public UploadReportController(IWebHostEnvironment environment, DicServerContext _ctx)
 {
     _environment = environment;
     ctx          = _ctx;
 }
 public StatsController(IWebHostEnvironment environment, DicServerContext context)
 {
     env = environment;
     ctx = context;
 }
        public HttpResponseMessage UploadStatsV2()
        {
            HttpResponseMessage response = new HttpResponseMessage {
                StatusCode = HttpStatusCode.OK
            };

            try
            {
                HttpRequest request = HttpContext.Current.Request;

                StreamReader sr       = new StreamReader(request.InputStream);
                StatsDto     newstats = JsonConvert.DeserializeObject <StatsDto>(sr.ReadToEnd());

                if (newstats == null)
                {
                    response.Content = new StringContent("notstats", Encoding.UTF8, "text/plain");
                    return(response);
                }

                DicServerContext ctx = new DicServerContext();

                if (newstats.Commands != null)
                {
                    foreach (NameValueStats nvs in newstats.Commands)
                    {
                        Command existing = ctx.Commands.FirstOrDefault(c => c.Name == nvs.name);

                        if (existing == null)
                        {
                            ctx.Commands.Add(new Command {
                                Name = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.Versions != null)
                {
                    foreach (NameValueStats nvs in newstats.Versions)
                    {
                        Version existing = ctx.Versions.FirstOrDefault(c => c.Value == nvs.name);

                        if (existing == null)
                        {
                            ctx.Versions.Add(new Version {
                                Value = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.Filesystems != null)
                {
                    foreach (NameValueStats nvs in newstats.Filesystems)
                    {
                        Filesystem existing = ctx.Filesystems.FirstOrDefault(c => c.Name == nvs.name);

                        if (existing == null)
                        {
                            ctx.Filesystems.Add(new Filesystem {
                                Name = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.Partitions != null)
                {
                    foreach (NameValueStats nvs in newstats.Partitions)
                    {
                        Partition existing = ctx.Partitions.FirstOrDefault(c => c.Name == nvs.name);

                        if (existing == null)
                        {
                            ctx.Partitions.Add(new Partition {
                                Name = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.MediaFormats != null)
                {
                    foreach (NameValueStats nvs in newstats.MediaFormats)
                    {
                        MediaFormat existing = ctx.MediaFormats.FirstOrDefault(c => c.Name == nvs.name);

                        if (existing == null)
                        {
                            ctx.MediaFormats.Add(new MediaFormat {
                                Name = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.Filters != null)
                {
                    foreach (NameValueStats nvs in newstats.Filters)
                    {
                        Filter existing = ctx.Filters.FirstOrDefault(c => c.Name == nvs.name);

                        if (existing == null)
                        {
                            ctx.Filters.Add(new Filter {
                                Name = nvs.name, Count = nvs.Value
                            });
                        }
                        else
                        {
                            existing.Count += nvs.Value;
                        }
                    }
                }

                if (newstats.OperatingSystems != null)
                {
                    foreach (OsStats operatingSystem in newstats.OperatingSystems)
                    {
                        OperatingSystem existing =
                            ctx.OperatingSystems.FirstOrDefault(c => c.Name == operatingSystem.name &&
                                                                c.Version == operatingSystem.version);

                        if (existing == null)
                        {
                            ctx.OperatingSystems.Add(new OperatingSystem
                            {
                                Name    = operatingSystem.name,
                                Version = operatingSystem.version,
                                Count   = operatingSystem.Value
                            });
                        }
                        else
                        {
                            existing.Count += operatingSystem.Value;
                        }
                    }
                }

                if (newstats.Medias != null)
                {
                    foreach (MediaStats media in newstats.Medias)
                    {
                        Media existing = ctx.Medias.FirstOrDefault(c => c.Type == media.type && c.Real == media.real);

                        if (existing == null)
                        {
                            ctx.Medias.Add(new Media {
                                Type = media.type, Real = media.real, Count = media.Value
                            });
                        }
                        else
                        {
                            existing.Count += media.Value;
                        }
                    }
                }

                if (newstats.Devices != null)
                {
                    foreach (DeviceStats device in newstats.Devices)
                    {
                        DeviceStat existing =
                            ctx.DeviceStats.FirstOrDefault(c => c.Bus == device.Bus &&
                                                           c.Manufacturer == device.Manufacturer &&
                                                           c.Model == device.Model &&
                                                           c.Revision == device.Revision);

                        if (existing == null)
                        {
                            ctx.DeviceStats.Add(new DeviceStat
                            {
                                Bus          = device.Bus,
                                Manufacturer = device.Manufacturer,
                                Model        = device.Model,
                                Revision     = device.Revision
                            });
                        }
                    }
                }

                ctx.SaveChanges();

                response.Content = new StringContent("ok", Encoding.UTF8, "text/plain");
                return(response);
            }
            // ReSharper disable once RedundantCatchClause
            catch
            {
                #if DEBUG
                if (Debugger.IsAttached)
                {
                    throw;
                }
                #endif
                response.Content = new StringContent("error", Encoding.UTF8, "text/plain");
                return(response);
            }
        }
 public ReportController(DicServerContext context) => _ctx = context;
Esempio n. 10
0
        public static void Convert(Stats newStats)
        {
            DicServerContext ctx = new DicServerContext();

            if (newStats.Commands != null)
            {
                if (newStats.Commands.Analyze > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "analyze");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Analyze, Name = "analyze"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Analyze;
                    }
                }

                if (newStats.Commands.Benchmark > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "benchmark");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Benchmark, Name = "benchmark"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Benchmark;
                    }
                }

                if (newStats.Commands.Checksum > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "checksum");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Checksum, Name = "checksum"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Checksum;
                    }
                }

                if (newStats.Commands.Compare > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "compare");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Compare, Name = "compare"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Compare;
                    }
                }

                if (newStats.Commands.CreateSidecar > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "create-sidecar");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command
                        {
                            Count = newStats.Commands.CreateSidecar, Name = "create-sidecar"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.CreateSidecar;
                    }
                }

                if (newStats.Commands.Decode > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "decode");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Decode, Name = "decode"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Decode;
                    }
                }

                if (newStats.Commands.DeviceInfo > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-info");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.DeviceInfo, Name = "device-info"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.DeviceInfo;
                    }
                }

                if (newStats.Commands.DeviceReport > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-report");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.DeviceReport, Name = "device-report"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.DeviceReport;
                    }
                }

                if (newStats.Commands.DumpMedia > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "dump-media");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.DumpMedia, Name = "dump-media"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.DumpMedia;
                    }
                }

                if (newStats.Commands.Entropy > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "entropy");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Entropy, Name = "entropy"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Entropy;
                    }
                }

                if (newStats.Commands.Formats > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "formats");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Formats, Name = "formats"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Formats;
                    }
                }

                if (newStats.Commands.MediaInfo > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-info");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.MediaInfo, Name = "media-info"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.MediaInfo;
                    }
                }

                if (newStats.Commands.MediaScan > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-scan");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.MediaScan, Name = "media-scan"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.MediaScan;
                    }
                }

                if (newStats.Commands.PrintHex > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "printhex");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.PrintHex, Name = "printhex"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.PrintHex;
                    }
                }

                if (newStats.Commands.Verify > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "verify");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Verify, Name = "verify"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Verify;
                    }
                }

                if (newStats.Commands.Ls > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "ls");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.Ls, Name = "ls"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.Ls;
                    }
                }

                if (newStats.Commands.ExtractFiles > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "extract-files");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.ExtractFiles, Name = "extract-files"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.ExtractFiles;
                    }
                }

                if (newStats.Commands.ListDevices > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-devices");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.ListDevices, Name = "list-devices"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.ListDevices;
                    }
                }

                if (newStats.Commands.ListEncodings > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-encodings");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command
                        {
                            Count = newStats.Commands.ListEncodings, Name = "list-encodings"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.ListEncodings;
                    }
                }

                if (newStats.Commands.ConvertImage > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "convert-image");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.ConvertImage, Name = "convert-image"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.ConvertImage;
                    }
                }

                if (newStats.Commands.ImageInfo > 0)
                {
                    Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "image-info");

                    if (existing == null)
                    {
                        ctx.Commands.Add(new Command {
                            Count = newStats.Commands.ImageInfo, Name = "image-info"
                        });
                    }
                    else
                    {
                        existing.Count += newStats.Commands.ImageInfo;
                    }
                }
            }

            if (newStats.OperatingSystems != null)
            {
                foreach (OsStats operatingSystem in newStats.OperatingSystems)
                {
                    if (string.IsNullOrWhiteSpace(operatingSystem.name) ||
                        string.IsNullOrWhiteSpace(operatingSystem.version))
                    {
                        continue;
                    }

                    OperatingSystem existing =
                        ctx.OperatingSystems.FirstOrDefault(c => c.Name == operatingSystem.name &&
                                                            c.Version == operatingSystem.version);

                    if (existing == null)
                    {
                        ctx.OperatingSystems.Add(new OperatingSystem
                        {
                            Count   = operatingSystem.Value,
                            Name    = operatingSystem.name,
                            Version = operatingSystem.version
                        });
                    }
                    else
                    {
                        existing.Count += operatingSystem.Value;
                    }
                }
            }
            else
            {
                OperatingSystem existing =
                    ctx.OperatingSystems.FirstOrDefault(c => c.Name == "Linux" && c.Version == null);

                if (existing == null)
                {
                    ctx.OperatingSystems.Add(new OperatingSystem {
                        Count = 1, Name = "Linux"
                    });
                }
                else
                {
                    existing.Count++;
                }
            }

            if (newStats.Versions != null)
            {
                foreach (NameValueStats nvs in newStats.Versions)
                {
                    if (string.IsNullOrWhiteSpace(nvs.name))
                    {
                        continue;
                    }

                    Version existing = ctx.Versions.FirstOrDefault(c => c.Value == nvs.name);

                    if (existing == null)
                    {
                        ctx.Versions.Add(new Version {
                            Count = nvs.Value, Value = nvs.name
                        });
                    }
                    else
                    {
                        existing.Count += nvs.Value;
                    }
                }
            }
            else
            {
                Version existing = ctx.Versions.FirstOrDefault(c => c.Value == "previous");

                if (existing == null)
                {
                    ctx.Versions.Add(new Version {
                        Count = 1, Value = "previous"
                    });
                }
                else
                {
                    existing.Count++;
                }
            }

            if (newStats.Filesystems != null)
            {
                foreach (NameValueStats nvs in newStats.Filesystems)
                {
                    if (string.IsNullOrWhiteSpace(nvs.name))
                    {
                        continue;
                    }

                    Filesystem existing = ctx.Filesystems.FirstOrDefault(c => c.Name == nvs.name);

                    if (existing == null)
                    {
                        ctx.Filesystems.Add(new Filesystem {
                            Count = nvs.Value, Name = nvs.name
                        });
                    }
                    else
                    {
                        existing.Count += nvs.Value;
                    }
                }
            }

            if (newStats.Partitions != null)
            {
                foreach (NameValueStats nvs in newStats.Partitions)
                {
                    if (string.IsNullOrWhiteSpace(nvs.name))
                    {
                        continue;
                    }

                    Partition existing = ctx.Partitions.FirstOrDefault(c => c.Name == nvs.name);

                    if (existing == null)
                    {
                        ctx.Partitions.Add(new Partition {
                            Count = nvs.Value, Name = nvs.name
                        });
                    }
                    else
                    {
                        existing.Count += nvs.Value;
                    }
                }
            }

            if (newStats.MediaImages != null)
            {
                foreach (NameValueStats nvs in newStats.MediaImages)
                {
                    if (string.IsNullOrWhiteSpace(nvs.name))
                    {
                        continue;
                    }

                    MediaFormat existing = ctx.MediaFormats.FirstOrDefault(c => c.Name == nvs.name);

                    if (existing == null)
                    {
                        ctx.MediaFormats.Add(new MediaFormat {
                            Count = nvs.Value, Name = nvs.name
                        });
                    }
                    else
                    {
                        existing.Count += nvs.Value;
                    }
                }
            }

            if (newStats.Filters != null)
            {
                foreach (NameValueStats nvs in newStats.Filters)
                {
                    if (string.IsNullOrWhiteSpace(nvs.name))
                    {
                        continue;
                    }

                    Filter existing = ctx.Filters.FirstOrDefault(c => c.Name == nvs.name);

                    if (existing == null)
                    {
                        ctx.Filters.Add(new Filter {
                            Count = nvs.Value, Name = nvs.name
                        });
                    }
                    else
                    {
                        existing.Count += nvs.Value;
                    }
                }
            }

            if (newStats.Devices != null)
            {
                foreach (DeviceStats device in newStats.Devices)
                {
                    if (string.IsNullOrWhiteSpace(device.Model))
                    {
                        continue;
                    }

                    if (!ctx.DeviceStats.Any(c => c.Bus == device.Bus && c.Manufacturer == device.Manufacturer &&
                                             c.Model == device.Model && c.Revision == device.Revision))
                    {
                        ctx.DeviceStats.Add(new DeviceStat
                        {
                            Bus          = device.Bus,
                            Manufacturer = device.Manufacturer,
                            Model        = device.Model,
                            Revision     = device.Revision
                        });
                    }
                }
            }

            if (newStats.Medias != null)
            {
                foreach (MediaStats media in newStats.Medias)
                {
                    if (string.IsNullOrWhiteSpace(media.type))
                    {
                        continue;
                    }

                    Media existing = ctx.Medias.FirstOrDefault(c => c.Type == media.type && c.Real == media.real);

                    if (existing == null)
                    {
                        ctx.Medias.Add(new Media {
                            Count = media.Value, Real = media.real, Type = media.type
                        });
                    }
                    else
                    {
                        existing.Count += media.Value;
                    }
                }
            }

            ctx.SaveChanges();
        }