Beispiel #1
0
        void checkForNewImagesInner(Context context, Settings settings)
        {
            Log.Info(LogTag, "Checking for new images to scale/etc/send");

            var db = ImageDatabaseAndroid.GetSingleton(context);

            Image[] images = db.getItemsToUpload();

            foreach (Image i in images)
            {
                string destfn = GetThumbnailPath(context, i);
                if (!File.Exists(destfn))
                {
                    scaleImage(i.sourcePath, destfn);
                }
                if (uploadImage(i, destfn, settings.authToken, (int)settings.defaultStream).Result)
                {
                    db.markSent(i.id);
                    if (settings.uploadNotifications)
                    {
                        Notifications.NotifyUpload(context, 200, true, "Uploaded image", "Uploaded image", "", i.sourcePath, destfn);
                    }
                }
            }
        }
 static public ImageDatabaseAndroid GetSingleton(Context context)
 {
     lock (s_lock)
     {
         if (s_global == null)
         {
             s_global = new ImageDatabaseAndroid(context.ApplicationContext);
         }
         return(s_global);
     }
 }
Beispiel #3
0
        async Task doCheck(Context context, Settings settings)
        {
            if (!settings.enabled || settings.authToken.IsNullOrEmpty())
            {
                Log.Info(LogTag, "App is disabled or not logged in; skipping download service check");
                return;
            }

            Log.Info(LogTag, "Doing new files check on server");

            // We pull the new check time up front because our snapshot of what images are available to
            // stream will be based on right now.
            //
            // FIXME: This isn't actually used right now; the REST call always pull the top 50.
            DateTimeOffset newCheckTime = DateTimeOffset.UtcNow;

            // Get a list of the user's subscribed streams. These are the ones we'll poll for new images.
            var subInfo = await Network.GetSubscriptionInfo(settings.authToken, (int)settings.userId);

            if (!subInfo.succeeded())
            {
                return;
            }

            string subList = String.Join(",", subInfo.subscriptions.Select(s => s.id.ToString()));

            // Call to the server to get our list of images to pull.
            var json = await Network.HttpGetToJsonAsync(Settings.BaseUrl + "api/stream/" + subList + "/contents", settings.authToken);

            var model = new Protocol.StreamContents(json);

            if (model.error != null)
            {
                Log.Error(LogTag, "Error checking for images on the server");
                return;
            }

            if (model.images.Length > 0)
            {
                // The total number of images we're waiting for in the media scanner callback.
                // This will be adjusted as we go for images we don't actually need to download.
                int imageCount = model.images.Length;

                // This will follow along behind our downloads and provide media server IDs that we
                // can feed to a notification, so that when the user taps on it, it'll take them to
                // that picture with their chosen app.
                //
                // This will also make the images available to the wider Android ecosystem by getting them
                // into the media scanner.
                //
                // We don't actually do a notification here until the last image, because otherwise
                // the user might get a flood of notifications if they've been offline or whatever.
                var completedImages      = new Dictionary <string, int>();
                int completedImagesTotal = 0;
                var scanner = new MediaScannerWrapper(context)
                {
                    scanned = (string path, Uri uri, Protocol.StreamContents.Image imgdata) =>
                    {
                        // Increment the count of per-user images.
                        if (!completedImages.ContainsKey(imgdata.userLogin))
                        {
                            completedImages[imgdata.userLogin] = 0;
                        }
                        ++completedImages[imgdata.userLogin];
                        ++completedImagesTotal;

                        // If this is the last image, we will push out a notification.
                        if (--imageCount == 0)
                        {
                            string message = GetNotificationMessage(completedImages, completedImagesTotal);
                            if (settings.downloadNotifications)
                            {
                                Notifications.NotifyDownload(context, 100, true, message, message, "", uri);
                            }
                        }
                    }
                };

                IImageDatabase db = ImageDatabaseAndroid.GetSingleton(context);

                foreach (var img in model.images)
                {
                    // If it's our image, don't download it.
                    if (img.userLogin == settings.userName)
                    {
                        Log.Info(LogTag, String.Format("Image {0} was ours; skipping download", img.filename));
                        --imageCount;
                        continue;
                    }

                    // Figure out where the image will go. Do a sanity check to make sure it doesn't contain an exploit.
                    string imgpath = Path.Combine(GetPath(img.userLogin), img.filename);
                    if (imgpath.Contains(".."))
                    {
                        Log.Error(LogTag, String.Format("Image name '{0}' is invalid. Skipping.", img.filename));
                        --imageCount;
                        continue;
                    }

                    if (db.getImageByUserAndFileName(img.userLogin, img.filename) != null)
                    {
                        Log.Info(LogTag, String.Format("Skipping image '{0}' as we already have it in our database.", img.filename));
                        --imageCount;
                        continue;
                    }

                    if (File.Exists(imgpath))
                    {
                        Log.Info(LogTag, String.Format("Skipping download of image '{0}' as we already seem to have the file.", img.filename));
                    }
                    else
                    {
                        Log.Info(LogTag, String.Format("Download image {0}/{1} to {2}", img.id, img.filename, imgpath));

                        await Network.HttpDownloadAsync(Settings.BaseUrl + "api/image/" + img.id, settings.authToken, imgpath);
                    }

                    db.addDownloadedFile(imgpath, img.filename, img.userLogin, img.uploadTime, img.comment);
                    scanner.addFile(imgpath, img);
                }

                scanner.scan();

                settings.lastCheck = newCheckTime;
                settings.commit();
            }

            Log.Info(LogTag, "File check complete.");
        }
Beispiel #4
0
 public GalleryAdapter(Context context)
 {
     _context = context;
     _db      = ImageDatabaseAndroid.GetSingleton(_context);
     _users   = _db.getUserSummaries();
 }
Beispiel #5
0
        public override void OnChange(bool selfChange)
        {
            // var newMedia = new List<Media>();
            long lastImageTimestamp = _settings.lastImageProcessedTimestamp;
            long newLastTimestamp   = -1;
            bool anyNew             = false;

            var uri = MediaStore.Images.Media.ExternalContentUri;

            using (var cursor = _context.ContentResolver.Query(
                       uri,
                       new String[] {
                MediaStore.MediaColumns.Data,
                MediaStore.MediaColumns.MimeType,
                MediaStore.MediaColumns.DateAdded
            },
                       // Skip files downloaded by DownloadService
                       MediaStore.MediaColumns.Data + " NOT LIKE ?",
                       new String[] {
                DownloadService.storageRoot + "%"
            },
                       "date_added DESC"
                       ))
            {
                int dataColumn      = cursor.GetColumnIndexOrThrow(MediaStore.MediaColumns.Data);
                int mimeTypeColumn  = cursor.GetColumnIndexOrThrow(MediaStore.MediaColumns.MimeType);
                int timestampColumn = cursor.GetColumnIndexOrThrow(MediaStore.MediaColumns.DateAdded);
                while (cursor.MoveToNext())
                {
                    if (cursor.IsNull(dataColumn))
                    {
                        Console.WriteLine("PhotoMediaObserver.OnChange(): filePath is null, which indicates this row is invalid (deleted?). Skip this file.");
                        continue;
                    }
                    string filePath  = cursor.GetString(dataColumn);
                    string mimeType  = cursor.GetString(mimeTypeColumn);
                    long   timestamp = cursor.GetLong(timestampColumn);

                    // This should only happen once because the records should be sorted, but >_>
                    if (timestamp > newLastTimestamp)
                    {
                        newLastTimestamp = timestamp;
                    }

                    if (timestamp > lastImageTimestamp)
                    {
                        Log.Info(LogTag, "Found file: {0} {1}", filePath, mimeType);
                        ImageDatabaseAndroid.GetSingleton(_context).addToUploadQueue(filePath, DateTimeOffset.UtcNow /*.AddMinutes(1)*/, "");
                        anyNew = true;
                    }
                }
            }

            // Update?
            if (newLastTimestamp > lastImageTimestamp)
            {
                _settings.lastImageProcessedTimestamp = newLastTimestamp;
                _settings.commit();
            }

            // If we found anything new, kick our services to get the pipeline moving.
            if (anyNew)
            {
                LifeSharpService.Instance.kickService <UploadService>();
            }
        }