diff --git a/.gitignore b/.gitignore index cbb855d..2fa008d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv/ *.sqlite3 migrations/ data/ +.vscode/ \ No newline at end of file diff --git a/app/charts/urls.py b/app/charts/urls.py index e0762a7..ae7fff3 100644 --- a/app/charts/urls.py +++ b/app/charts/urls.py @@ -1,110 +1,126 @@ -from django.conf.urls import url from django.urls import path from . import views urlpatterns = [ - # Pages URLs # Everyone can use these - path('', views.index, name='index'), - path('pricelog/', views.pricelog, name='pricelog'), - path('movingaverage/', views.movingaverage, name='movingaverage'), - path('pricelin/', views.pricelin, name='pricelin'), - path('powerlaw/', views.powerlaw, name='powerlaw'), - path('fractal/', views.fractal, name='fractal'), - path('golden/', views.golden, name='golden'), - path('competitors/', views.competitors, name='competitors'), - path('competitorslin/', views.competitorslin, name='competitorslin'), - path('competitorssats/', views.competitorssats, name='competitorssats'), - path('competitorssatslin/', views.competitorssatslin, name='competitorssatslin'), - path('translin/', views.translin, name='translin'), - path('translog/', views.translog, name='translog'), - path('metcalfesats/', views.metcalfesats, name='metcalfesats'), - path('metcalfeusd/', views.metcalfeusd, name='metcalfeusd'), - path('inflation/', views.inflation, name='inflation'), - path('coins/', views.coins, name='coins'), - path('extracoins/', views.extracoins, name='extracoins'), - path('sfmodel/', views.sfmodel, name='sfmodel'), - path('sfmodellin/', views.sfmodellin, name='sfmodellin'), - path('sfmultiple/', views.sfmultiple, name='sfmultiple'), - path('about/', views.about, name='about'), - path('compinflation/', views.compinflation, name='compinflation'), - path('bitcoin/', views.bitcoin, name='bitcoin'), - path('thermocap/', views.thermocap, name='thermocap'), - path('sharpe/', views.sharpe, name='sharpe'), - path('pricesats/', views.pricesats, name='pricesats'), - path('social/', views.social, name='social'), - path('social2/', views.social2, name='social2'), - path('social3/', views.social3, name='social3'), - path('social4/', views.social4, name='social4'), - path('social5/', views.social5, name='social5'), - path('social6/', views.social6, name='social6'), - path('social7/', views.social7, name='social7'), - path('hashrate/', views.hashrate, name='hashrate'), - path('hashprice/', views.hashprice, name='hashprice'), - path('hashvsprice/', views.hashvsprice, name='hashvsprice'), - path('inflationfractal/', views.inflationfractal, name='inflationfractal'), - path('dailyemission/', views.dailyemission, name='dailyemission'), - path('dailyemissionntv/', views.dailyemissionntv, name='dailyemissionntv'), - path('transcost/', views.transcost, name='transcost'), - path('transcostntv/', views.transcostntv, name='transcostntv'), - path('minerrevcap/', views.minerrevcap, name='minerrevcap'), - path('minerrev/', views.minerrev, name='minerrev'), - path('minerrevntv/', views.minerrevntv, name='minerrevntv'), - path('minerfees/', views.minerfees, name='minerfees'), - path('minerfeesntv/', views.minerfeesntv, name='minerfeesntv'), - path('commit/', views.commit, name='commit'), - path('commitntv/', views.commitntv, name='commitntv'), - path('inflationreturn/', views.inflationreturn, name='inflationreturn'), - path('dread_subscribers/', views.dread_subscribers, name='dread_subscribers'), - path('coincards/', views.coincards, name='coincards'), - path('merchants/', views.merchants, name='merchants'), - path('merchants_increase/', views.merchants_increase, name='merchants_increase'), - path('merchants_percentage/', views.merchants_percentage, name='merchants_percentage'), - path('dominance/', views.dominance, name='dominance'), - path('rank/', views.rank, name='rank'), - path('percentage/', views.percentage, name='percentage'), - path('marketcap/', views.marketcap, name='marketcap'), - path('tail_emission/', views.tail_emission, name='tail_emission'), - path('privacymarketcap/', views.privacymarketcap, name='privacymarketcap'), - path('privacydominance/', views.privacydominance, name='privacydominance'), - path('monerodominance/', views.monerodominance, name='monerodominance'), - path('blocksize/', views.blocksize, name='blocksize'), - path('transactionsize/', views.transactionsize, name='transactionsize'), - path('blockchainsize/', views.blockchainsize, name='blockchainsize'), - path('difficulty/', views.difficulty, name='difficulty'), - path('transmonth/', views.transmonth, name='transmonth'), - path('deviation/', views.deviation, name='deviation'), - path('deviation_tx/', views.deviation_tx, name='deviation_tx'), - path('transactiondominance/', views.transactiondominance, name='transactiondominance'), - path('percentmonth/', views.percentmonth, name='percentmonth'), - path('securitybudget/', views.securitybudget, name='securitybudget'), - path('efficiency/', views.efficiency, name='efficiency'), - path('p2pool_hashrate/', views.p2pool_hashrate, name='p2pool_hashrate'), - path('p2pool_dominance/', views.p2pool_dominance, name='p2pool_dominance'), - path('p2pool_miners/', views.p2pool_miners, name='p2pool_miners'), - path('p2pool_totalblocks/', views.p2pool_totalblocks, name='p2pool_totalblocks'), - path('metcalfesats_deviation/', views.metcalfesats_deviation, name='metcalfesats_deviation'), - path('metcalfe_deviation/', views.metcalfe_deviation, name='metcalfe_deviation'), - path('marketcycle/', views.marketcycle, name='marketcycle'), - path('shielded/', views.shielded, name='shielded'), - path('pricesatslog/', views.pricesatslog, name='pricesatslog'), - path('comptransactions/', views.comptransactions, name='comptransactions'), - path('p2pool_totalhashes/', views.p2pool_totalhashes, name='p2pool_totalhashes'), - path('miningprofitability/', views.miningprofitability, name='miningprofitability'), - path('withdrawals/', views.withdrawals, name='withdrawals'), - + path("", views.index, name="index"), + path("pricelog/", views.pricelog, name="pricelog"), + path("movingaverage/", views.movingaverage, name="movingaverage"), + path("pricelin/", views.pricelin, name="pricelin"), + path("powerlaw/", views.powerlaw, name="powerlaw"), + path("fractal/", views.fractal, name="fractal"), + path("golden/", views.golden, name="golden"), + path("competitors/", views.competitors, name="competitors"), + path("competitorslin/", views.competitorslin, name="competitorslin"), + path("competitorssats/", views.competitorssats, name="competitorssats"), + path("competitorssatslin/", views.competitorssatslin, name="competitorssatslin"), + path("translin/", views.translin, name="translin"), + path("translog/", views.translog, name="translog"), + path("metcalfesats/", views.metcalfesats, name="metcalfesats"), + path("metcalfeusd/", views.metcalfeusd, name="metcalfeusd"), + path("inflation/", views.inflation, name="inflation"), + path("coins/", views.coins, name="coins"), + path("extracoins/", views.extracoins, name="extracoins"), + path("sfmodel/", views.sfmodel, name="sfmodel"), + path("sfmodellin/", views.sfmodellin, name="sfmodellin"), + path("sfmultiple/", views.sfmultiple, name="sfmultiple"), + path("about/", views.about, name="about"), + path("compinflation/", views.compinflation, name="compinflation"), + path("bitcoin/", views.bitcoin, name="bitcoin"), + path("thermocap/", views.thermocap, name="thermocap"), + path("sharpe/", views.sharpe, name="sharpe"), + path("pricesats/", views.pricesats, name="pricesats"), + path("social/", views.social, name="social"), + path("social2/", views.social2, name="social2"), + path("social3/", views.social3, name="social3"), + path("social4/", views.social4, name="social4"), + path("social5/", views.social5, name="social5"), + path("social6/", views.social6, name="social6"), + path("social7/", views.social7, name="social7"), + path("hashrate/", views.hashrate, name="hashrate"), + path("hashprice/", views.hashprice, name="hashprice"), + path("hashvsprice/", views.hashvsprice, name="hashvsprice"), + path("inflationfractal/", views.inflationfractal, name="inflationfractal"), + path("dailyemission/", views.dailyemission, name="dailyemission"), + path("dailyemissionntv/", views.dailyemissionntv, name="dailyemissionntv"), + path("transcost/", views.transcost, name="transcost"), + path("transcostntv/", views.transcostntv, name="transcostntv"), + path("minerrevcap/", views.minerrevcap, name="minerrevcap"), + path("minerrev/", views.minerrev, name="minerrev"), + path("minerrevntv/", views.minerrevntv, name="minerrevntv"), + path("minerfees/", views.minerfees, name="minerfees"), + path("minerfeesntv/", views.minerfeesntv, name="minerfeesntv"), + path("commit/", views.commit, name="commit"), + path("commitntv/", views.commitntv, name="commitntv"), + path("inflationreturn/", views.inflationreturn, name="inflationreturn"), + path("dread_subscribers/", views.dread_subscribers, name="dread_subscribers"), + path("coincards/", views.coincards, name="coincards"), + path("merchants/", views.merchants, name="merchants"), + path("merchants_increase/", views.merchants_increase, name="merchants_increase"), + path( + "merchants_percentage/", views.merchants_percentage, name="merchants_percentage" + ), + path("dominance/", views.dominance, name="dominance"), + path("rank/", views.rank, name="rank"), + path("percentage/", views.percentage, name="percentage"), + path("marketcap/", views.marketcap, name="marketcap"), + path("tail_emission/", views.tail_emission, name="tail_emission"), + path("privacymarketcap/", views.privacymarketcap, name="privacymarketcap"), + path("privacydominance/", views.privacydominance, name="privacydominance"), + path("monerodominance/", views.monerodominance, name="monerodominance"), + path("blocksize/", views.blocksize, name="blocksize"), + path("transactionsize/", views.transactionsize, name="transactionsize"), + path("blockchainsize/", views.blockchainsize, name="blockchainsize"), + path("difficulty/", views.difficulty, name="difficulty"), + path("transmonth/", views.transmonth, name="transmonth"), + path("deviation/", views.deviation, name="deviation"), + path("deviation_tx/", views.deviation_tx, name="deviation_tx"), + path( + "transactiondominance/", views.transactiondominance, name="transactiondominance" + ), + path("percentmonth/", views.percentmonth, name="percentmonth"), + path("securitybudget/", views.securitybudget, name="securitybudget"), + path("efficiency/", views.efficiency, name="efficiency"), + path("p2pool_hashrate/", views.p2pool_hashrate, name="p2pool_hashrate"), + path("p2pool_dominance/", views.p2pool_dominance, name="p2pool_dominance"), + path("p2pool_miners/", views.p2pool_miners, name="p2pool_miners"), + path("p2pool_totalblocks/", views.p2pool_totalblocks, name="p2pool_totalblocks"), + path( + "metcalfesats_deviation/", + views.metcalfesats_deviation, + name="metcalfesats_deviation", + ), + path("metcalfe_deviation/", views.metcalfe_deviation, name="metcalfe_deviation"), + path("marketcycle/", views.marketcycle, name="marketcycle"), + path("shielded/", views.shielded, name="shielded"), + path("pricesatslog/", views.pricesatslog, name="pricesatslog"), + path("comptransactions/", views.comptransactions, name="comptransactions"), + path("p2pool_totalhashes/", views.p2pool_totalhashes, name="p2pool_totalhashes"), + path("miningprofitability/", views.miningprofitability, name="miningprofitability"), + path("withdrawals/", views.withdrawals, name="withdrawals"), # URLs to useful functions on charts/views.py - # Only admins can use these - path('get_history////', views.get_history, name='get_history'), - path('get_complete_history//', views.get_history, name='get_complete_history'), - path('load_dominance//', views.load_dominance, name='load_dominance'), - path('load_rank//', views.load_rank, name='load_rank'), - path('load_p2pool/', views.load_p2pool, name='load_p2pool'), - path('populate_database/', views.populate_database, name='populate_database'), - path('importer/', views.importer, name='importer'), - path('reset//', views.reset, name='reset'), - path('update///', views.update_database_admin, name='update'), - path('add_coin/', views.add_coin, name="add_coin"), - -] \ No newline at end of file + # Only admins can use these + path( + "get_history////", + views.get_history, + name="get_history", + ), + path( + "get_complete_history//", + views.get_history, + name="get_complete_history", + ), + path("load_dominance//", views.load_dominance, name="load_dominance"), + path("load_rank//", views.load_rank, name="load_rank"), + path("load_p2pool/", views.load_p2pool, name="load_p2pool"), + path("populate_database/", views.populate_database, name="populate_database"), + path("importer/", views.importer, name="importer"), + path("reset//", views.reset, name="reset"), + path( + "update///", + views.update_database_admin, + name="update", + ), + path("add_coin/", views.add_coin, name="add_coin"), +] diff --git a/app/moneropro/settings.py b/app/moneropro/settings.py index 7059ffc..8f6ec9d 100644 --- a/app/moneropro/settings.py +++ b/app/moneropro/settings.py @@ -14,99 +14,122 @@ import os from pathlib import Path # Necessary for assynchronous django -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rest.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rest.settings") os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" BASE_DIR = Path(__file__).resolve().parent.parent -#Comment for Local: +# TODO: Handle the following settings dynamically. + +# Comment for Local: DEBUG = False -#STATIC_ROOT = os.path.join(BASE_DIR, 'static') +# STATIC_ROOT = os.path.join(BASE_DIR, 'static') -#Comment for deploy: +# Comment for deploy: DEBUG = True -STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"),] +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, "static"), +] -STATIC_URL = '/static/' -LOCALE_PATHS = ( - os.path.join(BASE_DIR, "locale/"), -) +STATIC_URL = "/static/" +LOCALE_PATHS = (os.path.join(BASE_DIR, "locale/"),) # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'sdfasfasdfas324fdsfsd234234dsfdgdffdfghfdfasfasdasfadsffhgf675756748fas0f89as90fd8as9' -ALLOWED_HOSTS = ['www.moneroj.net', 'localhost', '127.0.0.1', 'moneroj.net', 'moneroj5xq4ttg4ec7e5secqdyw5mcovzvfvlq6i7omv353i6mnexlqd.onion'] +SECRET_KEY = "sdfasfasdfas324fdsfsd234234dsfdgdffdfghfdfasfasdasfadsffhgf675756748fas0f89as90fd8as9" # TODO: Move this somewhere else. +ALLOWED_HOSTS = [ + "www.moneroj.net", + "localhost", + "127.0.0.1", + "moneroj.net", + "moneroj5xq4ttg4ec7e5secqdyw5mcovzvfvlq6i7omv353i6mnexlqd.onion", +] # TODO: Move this somewhere else. + +if "MONEROPRO_DEV_HOST" in os.environ: + ALLOWED_HOSTS.append(os.environ["MONEROPRO_DEV_HOST"]) + +CORS_ALLOWED_ORIGINS = [f"http://{host}" for host in ALLOWED_HOSTS] + [ + f"https://{host}" for host in ALLOWED_HOSTS +] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'charts', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "charts", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", ] -ROOT_URLCONF = 'moneropro.urls' +ROOT_URLCONF = "moneropro.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'moneropro.wsgi.application' +WSGI_APPLICATION = "moneropro.wsgi.application" # Database + +# Handle old, questionable database location. +opt_path = Path("/opt/db.sqlite3") + +if opt_path.exists(): + opt_path.rename(BASE_DIR / "db.sqlite3") + DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': '/opt/db.sqlite3', - #'NAME': BASE_DIR / 'db.sqlite3', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } } +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + # Password validation AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization -LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +LANGUAGE_CODE = "en-us" +TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True diff --git a/app/moneropro/urls.py b/app/moneropro/urls.py index 074d7b8..120b17f 100644 --- a/app/moneropro/urls.py +++ b/app/moneropro/urls.py @@ -13,12 +13,11 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.conf.urls import include, url + from django.contrib import admin -from django.urls import path -from charts import views +from django.urls import path, include urlpatterns = [ - path('admin/', admin.site.urls), - url(r'', include(('charts.urls', 'charts'), namespace='charts')), + path("admin/", admin.site.urls), + path(r"", include(("charts.urls", "charts"), namespace="charts")), ] diff --git a/requirements.txt b/requirements.txt index 8eb057f..134aed0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,6 @@ beautifulsoup4==4.12.3 cachetools==5.5.0 chardet==4.0.0 # TODO: 5.2.0 – also, requests already depends on charset-normalizer, so why not use that? click==8.1.7 -dj-database-url==0.5.0 # TODO: 2.3.0 dj-static==0.0.6 # TODO: Serving statics should be done by the web server, not Django... Django==5.1.3 django-bootstrap4==24.4