-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7a787b6
Showing
141 changed files
with
23,545 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Compiled source # | ||
################### | ||
*.com | ||
*.class | ||
*.dll | ||
*.exe | ||
*.o | ||
*.so | ||
*.pyc | ||
*.pyo | ||
|
||
# Packages # | ||
############ | ||
# it's better to unpack these files and commit the raw source | ||
# git has its own built in compression methods | ||
*.7z | ||
*.dmg | ||
*.gz | ||
*.iso | ||
*.jar | ||
*.rar | ||
*.tar | ||
*.zip | ||
|
||
# Logs and databases # | ||
###################### | ||
*.log | ||
*.sql | ||
*.sqlite | ||
|
||
# OS generated files # | ||
###################### | ||
.DS_Store | ||
.DS_Store? | ||
._* | ||
.Spotlight-V100 | ||
.Trashes | ||
Icon? | ||
ehthumbs.db | ||
Thumbs.db | ||
|
||
# Development env # | ||
################### | ||
.project | ||
.sublime-project | ||
.pydevproject | ||
.idea | ||
|
||
# Ghiro custom files # | ||
###################### | ||
ghiro/secret_key.py | ||
logs/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. | ||
|
||
import os | ||
from django import forms | ||
from django.conf import settings | ||
from django.core.exceptions import ValidationError | ||
|
||
from analyses.models import Case, Analysis | ||
|
||
class CaseForm(forms.ModelForm): | ||
"""Case form.""" | ||
class Meta: | ||
model = Case | ||
|
||
class UploadImageForm(forms.ModelForm): | ||
"""Image upload form.""" | ||
image = forms.FileField(required=True) | ||
|
||
class Meta: | ||
model = Analysis | ||
fields = ["image"] | ||
|
||
def clean_image(self): | ||
image = self.cleaned_data.get("image", False) | ||
if image: | ||
# File check. | ||
if image._size > settings.MAX_FILE_UPLOAD: | ||
raise ValidationError("Image file too large") | ||
# Type check. | ||
file_type = image.content_type | ||
if not file_type in settings.ALLOWED_EXT: | ||
raise ValidationError("Image type not supported.") | ||
else: | ||
raise ValidationError("Image field is mandatory.") | ||
|
||
class ImageFolderForm(forms.Form): | ||
"""Folder upload form.""" | ||
path = forms.CharField(required=True) | ||
|
||
def clean_image(self): | ||
path = self.cleaned_data.get("path", False) | ||
if path: | ||
# Checks if it exist. | ||
if not os.path.exists(path): | ||
raise ValidationError("Specified path not found.") | ||
# Checks if is a directory. | ||
if not os.path.isdir(path): | ||
raise ValidationError("Specified path is not a directory.") | ||
else: | ||
raise ValidationError("Path field is mandatory.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. | ||
|
||
import logging | ||
from django.core.management.base import NoArgsCommand | ||
from django.utils.timezone import now | ||
from time import sleep | ||
|
||
import analyzer.db as db | ||
from analyses.models import Analysis | ||
from analyzer.images import AnalyzerRunner | ||
from analyzer.utils import HashComparer | ||
|
||
logger = logging.getLogger("processor") | ||
|
||
class Command(NoArgsCommand): | ||
"""Process images on analysis queue.""" | ||
|
||
help = "Image processing" | ||
|
||
option_list = NoArgsCommand.option_list | ||
|
||
def handle(self, *args, **options): | ||
"""Runs command.""" | ||
logger.debug("Starting processor...") | ||
|
||
try: | ||
self._process() | ||
except KeyboardInterrupt: | ||
print "Exiting... (requested by user)" | ||
self.is_running = False | ||
|
||
def _process(self): | ||
"""Starts processing waiting tasks.""" | ||
self.is_running = True | ||
while self.is_running: | ||
# Fetch tasks waiting processing. | ||
tasks = Analysis.objects.filter(state="W").order_by("id") | ||
|
||
if tasks: | ||
logger.info("Found {0} images waiting".format(tasks.count())) | ||
|
||
for task in tasks: | ||
logger.info("Processing task {0}".format(task.id)) | ||
|
||
try: | ||
logger.debug("Processing task {0}".format(task.id)) | ||
# Process. | ||
results = AnalyzerRunner(task.image_id, task.file_name).run() | ||
task.analysis_id = db.save_results(results) | ||
# Hash checks. | ||
HashComparer.run(results["hash"], task) | ||
# Complete. | ||
task.state = "C" | ||
logger.info("Processed task {0} with success".format(task.id)) | ||
except Exception as e: | ||
logger.exception("Error processing task {0}: {1}".format(task.id, e)) | ||
task.state = "F" | ||
finally: | ||
# Save. | ||
task.completed_at = now() | ||
task.save() | ||
|
||
logger.info("Done bunch") | ||
else: | ||
logger.debug("Waiting...") | ||
sleep(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. | ||
|
||
import magic | ||
import os | ||
from django.core.management.base import BaseCommand | ||
from optparse import make_option | ||
|
||
from analyses.models import Case, Analysis | ||
from users.models import Profile | ||
from analyzer.db import save_file | ||
from analyzer.utils import create_thumb | ||
|
||
|
||
class Command(BaseCommand): | ||
"""Image submission via command line.""" | ||
|
||
option_list = BaseCommand.option_list + ( | ||
make_option("--target", "-t", dest="target", | ||
help="Path of the file or directory to submit"), | ||
make_option("--case", "-c", dest="case", | ||
help="Case ID, images will be attached to it"), | ||
make_option("--username", "-u", dest="username", | ||
help="Username"), | ||
) | ||
|
||
help = "Task submission" | ||
|
||
def handle(self, *args, **options): | ||
"""Runs command.""" | ||
# Get options. | ||
user = Profile.objects.get(username=options["username"].strip()) | ||
case = Case.objects.get(pk=options["case"].strip()) | ||
|
||
# Add directory or files. | ||
if os.path.isdir(options["target"]): | ||
for file_name in os.listdir(options["target"]): | ||
print "INFO: processing {0}".format(file_name) | ||
self._add_task(os.path.join(options["target"], file_name), case, user) | ||
elif os.path.isfile(options["target"]): | ||
print "INFO: processing {0}".format(options["target"]) | ||
self._add_task(options["target"], case, user) | ||
else: | ||
print "ERROR: target is not a file or directory" | ||
|
||
def _add_task(self, file, case, user): | ||
"""Adds a new task to database. | ||
@param file: file path | ||
@param case: case id | ||
@param user: user id | ||
""" | ||
task = Analysis() | ||
task.owner = user | ||
task.case = case | ||
task.file_name = os.path.basename(file) | ||
mime = magic.Magic(mime=True) | ||
task.image_id = save_file(file_path=file, content_type=mime.from_file(file)) | ||
task.thumb_id = create_thumb(file) | ||
task.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. | ||
|
||
|
||
from bson.objectid import ObjectId | ||
from django.db import models | ||
from django.conf import settings | ||
|
||
from ghiro.common import mongo_connect | ||
from users.models import Profile | ||
|
||
db = mongo_connect() | ||
|
||
class Case(models.Model): | ||
"""Collection of image analysis.""" | ||
|
||
# Case state. | ||
STATUSES = ( | ||
("O", "Open"), | ||
("C", "Closed") | ||
) | ||
name = models.CharField(max_length=255, null=False, blank=False) | ||
description = models.TextField(null=True, blank=True) | ||
state = models.CharField(max_length=1, choices=STATUSES, default="O", db_index=True, editable=False, null=False, blank=False) | ||
owner = models.ForeignKey(Profile, null=False, blank=False, on_delete=models.CASCADE, db_index=True, editable=False, related_name="owned_cases") | ||
users = models.ManyToManyField(Profile, null=True, blank=True, db_index=True, related_name="cases") | ||
created_at = models.DateTimeField(auto_now_add=True, editable=False, db_index=True) | ||
updated_at = models.DateTimeField(auto_now=True, editable=False) | ||
|
||
class Meta: | ||
ordering = ["-created_at"] | ||
|
||
def save(self, *args, **kwargs): | ||
self.name = self.name.strip() | ||
if self.description: | ||
self.description = self.description.strip() | ||
super(Case, self).save(*args, **kwargs) | ||
|
||
class Analysis(models.Model): | ||
"""Image analysis.""" | ||
|
||
STATUSES = ( | ||
("W", "Waiting"), | ||
("C", "Completed"), | ||
("F", "Failed") | ||
) | ||
image_id = models.CharField(max_length=72, editable=False, null=False, blank=False) | ||
thumb_id = models.CharField(max_length=72, editable=False, null=True, blank=True) | ||
file_name = models.CharField(max_length=255, editable=False, null=False, blank=False) | ||
analysis_id = models.CharField(max_length=24, db_index=True, editable=False, null=True, blank=True) | ||
case = models.ForeignKey(Case, null=False, blank=False, on_delete=models.CASCADE, db_index=True, editable=False, related_name="images") | ||
owner = models.ForeignKey(Profile, null=False, blank=False, on_delete=models.CASCADE, db_index=True, editable=False, related_name="owned_images") | ||
state = models.CharField(max_length=1, choices=STATUSES, default="W", db_index=True, editable=False) | ||
created_at = models.DateTimeField(auto_now_add=True, editable=False, db_index=True) | ||
completed_at = models.DateTimeField(null=True, blank=True) | ||
|
||
class Meta: | ||
ordering = ["-created_at"] | ||
|
||
@property | ||
def latitude(self): | ||
"""Lookups latitude on mongo.""" | ||
try: | ||
record = db.analyses.find_one({"_id": ObjectId(self.analysis_id)}) | ||
except: | ||
return None | ||
|
||
if "gps" in record["metadata"]: | ||
return record["metadata"]["gps"]["pos"]["Latitude"] | ||
|
||
@property | ||
def longitude(self): | ||
"""Lookups longitude on mongo.""" | ||
try: | ||
record = db.analyses.find_one({"_id": ObjectId(self.analysis_id)}) | ||
except: | ||
return None | ||
|
||
if "gps" in record["metadata"]: | ||
return record["metadata"]["gps"]["pos"]["Longitude"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ghiro - Copyright (C) 2013 Ghiro Developers. | ||
# This file is part of Ghiro. | ||
# See the file 'docs/LICENSE.txt' for license terms. |
Oops, something went wrong.